動態規劃 揹包問題 01揹包

2021-09-29 22:13:59 字數 1354 閱讀 2300

有n種物品和乙個容量為v的揹包,每種物品僅用一次。第i件物品的費用是w[i],價值是v[i]。求解將哪些物品裝入揹包可使價值總和最大。

例如:n=5,v=10

重量   價值

第乙個物品: 10     5

第二個物品: 1     4

第三個物品: 2     3

第四個物品: 3     2

第五個物品: 4     1

首先我們考慮貪心策略,選取最大價值物品裝入揹包,得到的最大價值為:5。

但是正解為10(後四個物品)。所以我們直接來看揹包演算法。

定義dp[i][j]:選取i個物品,揹包容量為j時,所能獲得的最大價值。

由於乙個物品只能拿一次或者不拿,那麼我們分別分析拿還是不拿。

(1)j < w[i],這時揹包容量不足以放下第i件物品,只能不拿dp[i][j] = dp[i-1][j]

(2)j > w[i],這時揹包可以放下第i件物品,但是這時我們需要考慮拿這件物品是否會獲得更大價值。

那麼到底拿還是不拿,就需要比較哪個結果更大

這就是動態規劃的思想:在求值的時候考慮之前的狀態。綜上所述,我們得到了

狀態轉移方程:

if(j >= w[i])

dp[ i ][ j ] = max( dp[ i - 1 ][ j ], dp[ i - 1][ j - w[ i ] ] + v[ i ] );

else

dp[ i ][ j ] = dp[ i - 1 ][ j ];

注意到每次求解dp[i][j]值用到了上一行(i-1)的值:dp[i-1][j] 和 dp[i-1][j-w[i]],考慮用dp[j]來表示之前dp[i][j]的狀態。

那麼在計算第 i 次迴圈的dp值時,拿或者不拿的選擇變為下列情況:

至此,我們得到了空間壓縮後的狀態轉移方程:

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

}

注意:外層迴圈為第 i 件物品,內層迴圈為揹包價值,在壓縮空間之後,內層迴圈的順序不可更改,必須為降序,這是因為,由於將空間壓縮成一維陣列,所以只能儲存某一種時刻的狀態,但是我們的dp方程,需要利用上一狀態的值,也就是,dp[ j - w[ i ] ] 這句,並且,很顯然,用到位置是容量 < 當前容量( j )的值,也就是說,我們更改dp[ j ]的值時候,必須保證,j 之前的數值為上個狀態的值,不能優先於 j 更新。所以必須按照從大到小的次序更新。

動態規劃揹包問題 01揹包

問題描述 n種物品,每種乙個。第i種物品的體積為vi,重量為wi。選一些物品裝到容量為c的揹包,使得揹包內物品不超過c的前提下,重量最大。問題分析 宣告乙個f n c 的陣列。f i j 表示把前i件物品都裝到容量為j的揹包所獲得的最大重量。當 j v i 時,揹包容量不足以放下第 i 件物品,f ...

動態規劃 揹包問題(01揹包 完全揹包)

揹包問題 多種物品 重量不同 價值不同 你可以取最多重量不超過w的物品,問最大價值為多少?01揹包 指的是 有n個物品 每個物品的重量為w i 價值為v i 每個物品只有乙個 所有面臨這些物品只有兩種結果 1 拿這件物品,揹包容量減去w i 此時的價值增加v i 2 不拿這件物品,揹包容量不變,最大...

動態規劃 01揹包 完全揹包

有一類動態規劃可解的問題,它可以描述稱為若干有序的階段,且每個階段的狀態只和上乙個階段的狀態有關,一般把這類問題稱為多階段規劃問題。01揹包問題描述如下 有 n 件物品,每件物品的重量為 w i 價值為 c i 現有乙個容量為 v 的揹包,問如何選取物品放入揹包,使得揹包內物品的總價值最大。其中每種...