動態規劃 (三) 揹包問題

2021-06-25 08:02:35 字數 1950 閱讀 8367

有n個物品,且每個物品都只有乙個。物品i的體積為v[ i ],重量為w[ i ]。揹包的體積為c,求怎樣裝載能使得揹包裡裝的物品最重?

之所以叫0-1揹包問題,是因為所有的物品都只有乙個,在選擇物品裝載到揹包裡的時候,只有兩種選擇:不裝載或裝載,對應計算機裡的0(false)和1(true)的概念。我們用 dp[ i ][ j ] 表示「把前 i 個物品裝到體積為 j 的揹包中的最大總重量」。得狀態轉移方程:

dp[i][j] = max(dp[i-1][j], dp[i-1][j - v[i]] + w[i]);
其中,dp[ i - 1 ][ j ] 表示不把物品 i 裝載進揹包,所以揹包的重量是前面 i-1 個的重量;後一項 dp[ i - 1][ j - v[ i ] ] + w[ i ] 表示若把第 i 個物品裝載進揹包,則必須由最優子問題得到,所以沒裝載 i 之前重量一定也是最大的。

我們發現迴圈的時候,這個轉移方程是乙個二維陣列,且第 i 行取決於第 i -1行的值,因此初始化時,只要將第 0 行全部置為 0 即可,即 dp[ 0 ] [ j ] = 0;

for(int j = 0; j <= c; ++ j) 

for(int i = 1; i <= n; ++ i) else

}}

dp[ i ][ j ] 表示「把前 i 個物品裝到體積為 j 的揹包中的最大總重量」。所以外迴圈 i 表示從前1個物品到前n個物品,內迴圈 j 表示體積從 0 到 最大的 c。由於資料是一樣樣計算的,所以可以不用提前把所有的資料都讀好,也不用存起來。

更奇妙的是,我們可以把陣列dp程式設計一維的,這裡非常的精妙和巧合,但是要注意這只是程式**的優化,並不是說 0 - 1 揹包問題就是一維揹包問題。

memset(dp, 0, sizeof(dp)); 

for (int i = 1; i <= n; ++ i)

}

考慮為採用滾動陣列的情況,f[ i ][ j ]的值要麼是f[ i - 1][ j ],要麼是f[ i - 1][ j  - v ] + w;由於j是從右往左計算的,所以現在f[j]裡儲存的是f[ i - 1 ] [ j ],而f[j - v]裡儲存的是f[ i - 1 ] [ j - v ]的值,所以正好可以。這樣子的話,我們可以節省了不少空間的代價。 

注意內迴圈 j 是到 v 即停止了的,這樣子就不用判斷 j 和 v 的關係了,因為 j >= v 始終成立。若是 j  < v 的情況,f[ j ] 中本來就儲存了 f[ i - 1][ j ]的資訊,也不用更新。

此外,若題目要求,揹包必須裝滿,則只需要改一下初始化的條件就行。

memset(dp, -0x3f3f, sizeof(dp));

dp[0] = 0;

for(int i = 1; i <= n; ++ i)

}

揹包九講裡是這樣子解釋的:初始化的過程,實際就是說,當一件物品都沒有時的解。所以若要求必須裝滿揹包,只有一種解,就是dp[0],即讓價值為0的物品,恰好裝進容量為0的包裡。其他的都是非法解,所以初始化為負∞才行。而沒有要求一定要裝滿揹包的情況下,則所有的解都可以是正確的解,所以可以初始化為0;

可重複揹包是說,每種物品的個數是無限的,而不是0-1揹包中,物品只有乙個。相似的,有狀態轉移方程:

dp[i][v]=max
就是說,這個物品可以選 0 次,1 次,2次... v / c[i] 次,知道裝不下為止。

但是也有o(nv)複雜度的優化,而且**很簡單,就是上面的滾動陣列實現0-1揹包,內迴圈 j 倒過來就行了。原理不明,可能是我水平太低了,目前無法理解。

偽**如下:

procedure completepack(cost,weight)

for v=cost..v

f[v]=max

動態規劃 揹包問題

給定n個物品,重量是,價值是,包的容量 承重 是w 問,放入哪些物品能使得包內價值最大 1 需要將問題轉化為子問題,通過遞迴實現,且子問題必然與父問題存在關聯 2 定義v i,j 表示為,當item取自前i個items且揹包capacity j 時,揹包問題的最優解,也即最高的價值。3 從前i個it...

動態規劃 揹包問題

不廢話,直接上 動態規劃,揹包問題。輸入為 int n 物品的種類數。int n weight 各件物品的重量。int n value 各種物品的價值。int w 揹包最大的裝載重量。輸出 v n b 的值,最大的裝載價值。x n 各類物品的裝載數量。author huangyongye publi...

動態規劃 揹包問題

1 開心的金明 問題描述 金明今天很開心,家裡購置的新房就要領鑰匙了,新房裡有一間他自己專用的很寬敞的房間。更讓他高興的是,媽媽昨天對他說 你的房間需要購買哪些物品,怎麼布置,你說了算,只要不超過n 元錢就行 今天一早金明就開始做預算,但是他想買的東西太多了,肯定會超過媽媽限定的n 元。於是,他把每...