多重背包通过二进制分组转化为01背包
算法讲解075【必备】背包dp-多重背包、混合背包_哔哩哔哩_bilibili
对于每个物品的数量可以用二进制的方式进行拆分:
比如说一个物品有13个
可以被拿走的范围是0-13
我们可以将13分为1+2+4+7
可以发现3可以被1+2
5可以被1+4
依次进行可以发现这样分组后0-13都可以被表示出来非常的巧妙
#include<bits/stdc++.h> using namespace std; const int N=200005; int n,W; int v[N],w[N],sum,f[N]; signed main() { ios::sync_with_stdio(0); cin.tie(0); cin>>n>>W; for(int i=1;i<=n;i++) { int x,y,cnt; cin>>x>>y>>cnt; for(int k=1;k<=cnt;k<<=1) { v[++sum]=k*x; w[sum]=k*y; cnt-=k; } if(cnt>0) { v[++sum]=cnt*x; w[sum]=cnt*y; } } //for(int i=1;i<=sum;i++)cout<<v[i]<<' '<<w[i]<<endl; for(int i=1;i<=sum;i++) for(int j=W;j>=w[i];j--) { f[j]=max(f[j],f[j-w[i]]+v[i]); } cout<<f[W]; return 0; }