DP 揹包問題

2021-07-30 06:59:54 字數 1449 閱讀 6975

**大牛

以下使用滾到陣列(若輸入要求一般,可以邊定義狀態邊輸入,不需儲存)     +    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的揹包,每種物品...