有 N 种物品和一个容量是 V 的背包。
物品一共有三类:
- 第一类物品只能用1次(s<0时)(01背包);
- 第二类物品可以用无限次(s=0时)(完全背包);
- 第三类物品最多只能用 $s_i$ 次(s>0时)(多重背包);
每种体积是 $v_i$,价值是 $w_i$。
- 求解将哪些物品装入背包,可使物品体积总和不超过背包容量,且价值总和最大。
输出最大价值。
思路:
按类别处理就行,要注意的就是将多重背包转化为二进制优化的01背包就行。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| #include <iostream> #include <vector> #include <algorithm> using namespace std; const int N=1010; int f[N]; int n,m; struct Goods{ int type,v,w; }; vector<Goods>goods; int main(){ cin>>n>>m; for(int i=0;i<n;i++){ int v,w,s; cin>>v>>w>>s; if(s>0){ for(int k=1;k<=s;k*=2){ goods.push_back({-1,k*v,k*w}); s-=k; } if(s>0)goods.push_back({-1,s*v,s*w}); } else goods.push_back({s,v,w}); } for(auto g:goods){ if(!g.type){ for(int j=g.v;j<=m;j++)f[j] = max(f[j],f[j-g.v]+g.w); }else { for(int j=m;j>=g.v;j--)f[j] = max(f[j],f[j-g.v]+g.w); } } cout<<f[m]<<endl; return 0; }
|