acwing 3 徹底揹包

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

題目描述
有 N 種物品和一個容量是 V 的揹包,每種物品都有無限件可用。算法

第 i 種物品的體積是 vi,價值是 wi。ide

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

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

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

輸出格式
輸出一個整數,表示最大價值。ip

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

樣例get

輸入樣例
4 5
1 2
2 4
3 4
4 5
輸出樣例:
10

算法1
幾乎與01揹包的一維解答如出一轍,惟一的區別是v的遍歷次序是遞增的。
那麼就是說明dp轉移方程
dp[j] = max(dp[j] , dp[j-v[i]]+w[i]);
dp依賴的狀態未必是i-1輪的狀態 而是同一輪中較小的j。 這也符合題意。
01揹包中要驗證當前第i個物品是否拿仍是不拿必須依賴上一輪(i-1)輪的狀態,這個狀態是絕對不會出現已經拿取了第i個物品的狀況。
可是在徹底揹包中,因爲物品有多個,可能要驗證當前是否拿第i個物品所依賴的狀態已經取過若干個第i個物品了
因此v的遍歷是由小到大遞增的。it

C++ 代碼

 1 #include <iostream>
 2 #include <algorithm>
 3 
 4 using namespace std;
 5 
 6 const int N= 1010;
 7 
 8 int n,m;
 9 
10 int arr[N];
11 int v[N];
12 int w[N];
13 
14 int main()
15 {
16     cin >> n >> m;
17 
18     for(int i = 1;i <= n;i++){
19         cin >> v[i] >> w[i];
20     }
21 
22     for(int i = 1;i<=n;i++){
23         for(int j = v[i];j <= m ;j++){
24             arr[j] = max(arr[j] , arr[j-v[i]]+w[i]);
25         }
26     }
27 
28     cout << arr[m];
29 
30     return 0;   
31 }
32 
33 做者:defddr
34 連接:https://www.acwing.com/solution/AcWing/content/2191/
35 來源:AcWing
36 著做權歸做者全部。商業轉載請聯繫做者得到受權,非商業轉載請註明出處。
View Code
相關文章
相關標籤/搜索