**大牛
以下使用滾到陣列(若輸入要求一般,可以邊定義狀態邊輸入,不需儲存) + memset( f, 0, sizeof(int) * n); 若求最小值,除 f[0] , 其餘初始化為 inf,f[0] = 0是必須的(求最大最小都一樣), 確保有從無到有的起點
0 - 1揹包 (一般形式 f[i][v] = max( f[i-1][v], f[i-1][v - c[i]] + w[i] ))
for ( j = c; j >= c[i]; --j )
逆序, 從右往左, 上往下重新整理, 確保只有乙個
完全揹包 (一般形式 f[i][v] = max( f[i-1][v], f[i-1][v-k*c[i]] + k * w[i] ))
for ( j = c[i]; j <= c; ++j )
正序, 從左往右重新整理, 把 k(數量) 內建
for ( int i = 1; i <= n; ++i )
用滾動陣列 的完全揹包是
沒有出現 與 k(數量) 有關的迴圈 + 乘數 的限制的,因為內化在了從左到右重新整理的迴圈裡
for(int i = 1; i <= n; ++i)
!!!這種做法資料大可能會超時
以下引入
二分制優化和多組揹包思想
如 價值 v = 1, 占用為 c = 2, 數量為 n = 12 的揹包
按如上(非2分制演算法) 思想是將
把有數量為12 的樣品i 分為 12個物品
2分制法 : 12 = 1 + 2 + 4 +
5
(2的倍數)
分為了4個物品, 最後乙個是差, 如 13 = 1 + 2 + 4 + 6
則任何乙個價值的物品都可以由被拆分的物品表示, 如 2 = 2, 3 = 1 + 2; 5 = 1 + 4;
** :
void completepack(int cost,int weight) //完全揹包
void zeroonepack(int cost,int weight) // 01揹包
void dp(int cost,int weight,int k)
zeroonepack(k*cost,k*weight);}}
揹包問題 DP
01揹包 現在有1個體積為mmax的揹包和n種物品 每種物品只有1個 每種物品的體積和價值分別是v i 和w i 求這個揹包最多可以裝價值多少的物品。這是最基礎的揹包問題,特點是 每種物品僅有一件,可以選擇放或不放。用子問題定義狀態 設f i j 表示前i件物品恰放入乙個容量為j的揹包可以獲得的最大...
DP 揹包問題
小明同學在參加一場考試,考試時間2個小時。試卷上一共有n道題目,小明要在規定時間內,完成一定數量的題目。考試中不限制試題作答順序,對於 i 第道題目,小明有三種不同的策略可以選擇 1 直接跳過這道題目,不花費時間,本題得0分。2 只做一部分題目,花費pi分鐘的時間,本題可以得到ai分。3 做完整個題...
dp 揹包問題
乙個揹包總容量為v,現在有n個物品,第i個物品容量為weight i 價值為value i 現在往揹包裡面裝東西,怎樣裝才能使揹包內物品總價值最大.主要分為3類 總體的,又分為揹包剛好裝滿,與揹包沒有裝滿兩種情況 每種物品都只有1個,只有選擇與不選擇兩種狀態 有n件物品和乙個容量為v的揹包,每種物品...