有n
nn種物品和乙個容量是v
vv的揹包。第i
ii種物品最多有s
is_i
si件,每件體積是v
iv_i
vi,價值是w
iw_i
wi。求解將哪些物品裝入揹包,可使物品體積總和不超過揹包容量,且價值總和最大。輸出最大價值。
輸入格式:
第一行兩個整數,n
nn,v
vv,用空格隔開,分別表示物品種數和揹包容積。接下來有n
nn行,每行三個整數vi,
wi,s
iv_i,w_i,s_i
vi,wi
,si
,用空格隔開,分別表示第i
ii種物品的體積、價值和數量。
輸出格式:
輸出乙個整數,表示最大價值。
資料範圍:
0
1000 0< n\le 1000 01000 0 2000 0< v\le 2000 02000 0 ,wi, si ≤2000 00,wi ,si ≤20 00思路是動態規劃。但這裡需要用二進位制優化,其基本思路是,將每個物品的個數s ss拆成若干個形如2 k2^k 2k的個數的」打包」,這樣就將多重揹包問題轉為了0−1 0-10− 1揹包問題了,從而將時間複雜度降為o(v ∑i=1 nlogs i) o(v\sum_^ \log s_i) o(v∑i= 1nlogsi )。例如,如果乙個物品有10 1010 個,那麼可以將它拆成1+2 +22+ 31+2+2^2+3 1+2+22 +3,這樣這個物品的所有取法,一定包含於將其拆成若干小塊,每個小塊最多取乙個的取法。其正確性證明參考**如下: using namespace std; const int n = 25000 , m = 2010 ;int n, m; int v[n] , w[n] ;int f[n] ;int main() // 如果沒拆乾淨,把剩餘的部分也打包 if(s >0) }// 拆完後新的個數重新賦值,然後做0-1揹包 n = cnt; for( int i = 1; i <= n; i++ )for (int j = m; j >= 0; j--)if (j >= v[i] ) f[j] =max (f[j] , f[j - v[i] ]+ w[i]); cout << f[m] << endl; return0; }時間複雜度o(( ∑i=1 nlogs i)v) o((\sum_^ \log s_i) v) o((∑i= 1nlogsi )v) ,空間o(v )o(v) o(v) 。**裡n nn開25000 25000 2500 0是1000 ×log 2000 1000\times \log 2000 1000 ×log20 00算出來的。 題目描述 有 n 種物品和乙個容量是 v的揹包。第 i種物品最多有 si 件,每件體積是 vi,價值是 wi。求解將哪些物品裝入揹包,可使物品體積總和不超過揹包容量,且價值總和最大。輸出最大價值。輸入格式 第一行兩個整數,n,v,用空格隔開,分別表示物品種數和揹包容積。接下來有 n行,每行三個整數 ... 有 n 種物品和乙個容量是 v 的揹包。第 i 種物品最多有 si 件,每件體積是 vi,價值是 wi。求解將哪些物品裝入揹包,可使物品體積總和不超過揹包容量,且價值總和最大。輸出最大價值。輸入格式 第一行兩個整數,n,v,用空格隔開,分別表示物品種數和揹包容積。接下來有 n 行,每行三個整數 vi... 有 n 種物品和乙個容量是 v 的揹包。第 i 種物品最多有 si 件,每件體積是 vi,價值是 wi。求解將哪些物品裝入揹包,可使物品體積總和不超過揹包容量,且價值總和最大。輸出最大價值。輸入格式 第一行兩個整數,n,v,用空格隔開,分別表示物品種數和揹包容積。接下來有 n 行,每行三個整數 vi...#include
AcWing 5 多重揹包問題 II
acwing 5 多重揹包問題 II
多重揹包問題 II