黑科技:优化多重背包
黑科技之:优化多重背包
优化方法1:二进制优化
思想:把v[i]个物品拆成1、2、4、...、2^k、剩下的,然后01背包
代码:
#include <algorithm> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <ctime> #include <iostream> #include <map> #include <queue> #include <set> #include <stack> #include <string> #include <vector> #include <cctype> using namespace std; #define rep(i,x,y) for(int i=x;i<=y;i++) #define frep(i,x,y) for(int i=x;i>=y;i--) #define ll long long struct bag { int v; int w; }; const int N=10000005; int n; ll t; ll val[N],w[N]; int cnt=0; bag a[N]; ll f[N]; ll ans=0; int main() { scanf("%d%lld",&n,&t); rep(i,1,n) { ll W; scanf("%lld%lld%lld",&val[i],&w[i],&W); for(ll j=1;j<=W;j<<=1) { cnt++; a[cnt].v=val[i]*j; a[cnt].w=w[i]*j; W-=j; } if(W) { cnt++; a[cnt].v=val[i]*W; a[cnt].w=w[i]*W; } } n=cnt; rep(i,1,n) { frep(j,t,a[i].w) { f[j]=max(f[j],f[j-a[i].w]+a[i].v); } } rep(i,0,t) ans=max(ans,f[i]); printf("%lld\n",ans); return 0; }
优化方法2:单调队列优化
不会
优化方法3:神奇优化
对于同一类出现次数>2的数
两个合并一下
合并到最后,结束
例子: