acwing 7 混合揹包

習題地址  https://www.acwing.com/problem/content/description/7/ios

 

題目描述
有 N 種物品和一個容量是 V 的揹包。算法

物品一共有三類:ide

第一類物品只能用1次(01揹包);
第二類物品能夠用無限次(徹底揹包);
第三類物品最多隻能用 si 次(多重揹包);
每種體積是 vi,價值是 wi。優化

求解將哪些物品裝入揹包,可以使物品體積總和不超過揹包容量,且價值總和最大。
輸出最大價值。spa

輸入格式
第一行兩個整數,N,V,用空格隔開,分別表示物品種數和揹包容積。code

接下來有 N 行,每行三個整數 vi,wi,si,用空格隔開,分別表示第 i 種物品的體積、價值和數量。blog

si=−1 表示第 i 種物品只能用1次;
si=0 表示第 i 種物品能夠用無限次;
si>0 表示第 i 種物品能夠使用 si 次;
輸出格式
輸出一個整數,表示最大價值。ip

數據範圍
0<N,V≤1000
0<vi,wi≤1000
−1≤si≤1000ci

輸入樣例
4 5
1 2 -1
2 4 1
3 4 0
4 5 2
輸出樣例:
8

 

算法1
前三種揹包處理的混合型號
01 揹包則直接放入數據容器中
多重揹包則化解成 01 揹包 放入數據容器中(見多重揹包II習題 進行二進制優化)
徹底揹包也直接放入數據容器中get

此刻數據容器vector[HTML_REMOVED] things;中就只有01揹包和徹底揹包 那麼就進行遍歷處理

 1 #include <iostream>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <vector>
 5 
 6 using namespace std;
 7 
 8 const int N = 1010;
 9 
10 int n,m;
11 int f[N];
12 
13 struct Thing{
14     int kind;
15     int v,w;
16 };
17 vector<Thing> things;
18 
19 
20 int main()
21 {
22     cin >> n>>m;
23     for(int i = 0;i<n;i++)
24     {
25         int v,w,s;
26         cin >> v >> w>> s;
27         if(s < 0)
28         {
29             things.push_back({-1,v,w});
30         }else if(s == 0) things.push_back({0,v,w});
31         else{
32             for(int k = 1;k <= s; k*=2){
33                 s -=k;
34                 things.push_back({-1,v*k,w*k});
35             }
36             if(s > 0) things.push_back({-1,v*s,w*s});
37         }
38     }
39 
40     for(auto thing:things)
41     {
42         if(thing.kind < 0){
43             for(int j = m;j >= thing.v;j--) f[j] = max(f[j],f[j-thing.v]+thing.w);
44         }else{
45             for(int j = thing.v;j <= m;j++) f[j] = max(f[j],f[j-thing.v]+thing.w);
46         }
47     }
48 
49     cout << f[m] << endl;
50 
51     return 0;
52 }
53 
54 做者:defddr
55 連接:https://www.acwing.com/solution/acwing/content/2198/
56 來源:AcWing
57 著做權歸做者全部。商業轉載請聯繫做者得到受權,非商業轉載請註明出處。
View Code
相關文章
相關標籤/搜索