習題地址 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 著做權歸做者全部。商業轉載請聯繫做者得到受權,非商業轉載請註明出處。