動態規劃 01揹包問題

2021-10-04 14:07:34 字數 3233 閱讀 3988

問題描述:

給定 n 件物品,第 i 件的物品重量是 w[i] ,價值是 v[i],求在揹包承重為 m 時能存放物品的最大總價值。(每個物品僅有一件)。

問題分析:

動態規劃解01揹包:

核心是對於每種物品只有兩個選擇——放與不放。

用 dp[i][j] 表示前 i 件物品放入容量為 j 的空間時的最大價值。將第 i 件物品放入容量為 j 的空間,只有放與不放兩種選擇:

(1) 放不下(不放),則當前最大價值為 i-1 件物品放入容量為 j 的空間時的最大價值。即:dp[i][j]=dp[i-1][j];

(2) 放的下有兩種情況,取最大價值

①不放,當前最大價值為 i-1件物品放入容量為 j 的空間時的最大價值,即 dp[i][j]=dp[i-1][j];

②放,肯定就要騰出w[i]的空間(因為當前列舉的空間容量固定為 j ),則騰出後的空間為 j-w[i] ,所以此時最大價值為: i-1 件物品放入 j-w[i] 的空間的最大價值加上當前物品的價值。即dp[i][j]=dp[i-1][j-w[i]]+v[i]。

所以放得下的綜合式子為:dp[i][j]=max(dp[i-1][j],dp[i-1][j-w[i]]+v[i])

注: 這裡提到 i-1 件物品放入揹包的最大價值,並不意味著 i-1 件物品都被放進去了,只是說已經對 i-1 件物品做出了最大價值的選擇,實際可能放了可能沒放。當我們將 n 件物品放入[0,m]的空間全部做出最優選擇,答案也就出來了——dp[n][m]。

狀態轉移方程:

("揹包能承載的最大價值為:%d\n"

,dp[n]

[m])

;//回溯

int i=n,j=m;

while

(i>0)

i--;}

printf

("選擇的物品為:\n");

for(

int i=

1;i<=n;i++)if

(vis[i]

)printf

("%d號\t重量為%d\t價值為%d\n"

,i,w[i]

,v[i]);

return0;

}測試樣例:

5 10

2 62 3

6 55 4

4 6輸出:

揹包能承載的最大價值為:15

選擇的物品為:

1號 重量為2 價值為6

2號 重量為2 價值為3

5號 重量為4 價值為6

樣例填充圖:

5件物品,揹包最大承重為10。每個物品的具有重量和價值:【2,6】【2,3】【6,5】【5,4】【4,6】。

注: 結合**及樣例推導一遍此填充圖更有助於理解。

優化:以上方法的時間和空間複雜度均為o(n*m),我們還可以將空間複雜度優化到o(m)。

用dp[j]表示空間為 j 的所有方案中的最大價值。

狀態轉移方程:dp[j]=max(dp[j],dp[j-w[i]]+v[i]); (1<=i<=n,w[i]<=j<=m)

for

(int i =

1; i <= n; i++

)for

(int j = m; j >= w[i]

; j--

) dp[j]

=max

(dp[j]

,dp[j-w[i]

]+v[i]

);

原理: 核心是基於一維陣列做反向迭代,這樣的話j後面會用到前面的資料,而前面的資料可能是放過該物品後的,這樣就有可能導致放入該物品多次。

例:

有乙個物品w=

1,v=

2,狀態轉移方程:dp[j]

=max

(dp[j]

,dp[j-w[i]

]+v[i]);

正向迭代,初始狀態:dp[0]

=0 dp[1]

=0 dp[2]

=0 dp[3]

=0dp[0]=

0

dp[1]=

max(dp[1]

,dp[1-

1]+2

)=2dp[2]

=max

(dp[2]

,dp[2-

1]+2

)=4dp[3]

=max

(dp[3]

,dp[3-

1]+2

)=6可以看出該物品被放了三次,顯然是錯誤的

反向迭代,初始狀態dp[0]

=0 dp[1]

=0 dp[2]

=0 dp[3]

=0dp[3]=

max(dp[3]

,dp[3-

1]+2

)=2dp[2]

=max

(dp[2]

,dp[2-

1]+2

)=2dp[1]

=max

(dp[1]

,dp[1-

1]+2

)=2dp[0]

=0

**:

#include

#include

const

int maxn=

100;

int dp[maxn]

,w[maxn]

,v[maxn]

;int

max(

int a,

int b)

intmain()

動態規劃揹包問題 01揹包

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

動態規劃 揹包問題 01揹包

有n種物品和乙個容量為v的揹包,每種物品僅用一次。第i件物品的費用是w i 價值是v i 求解將哪些物品裝入揹包可使價值總和最大。例如 n 5,v 10 重量 價值 第乙個物品 10 5 第二個物品 1 4 第三個物品 2 3 第四個物品 3 2 第五個物品 4 1 首先我們考慮貪心策略,選取最大價...

0 1揹包問題(動態規劃)

一 問題描述 有n件物品和乙個容量為v的揹包。第i件物品的費用是c i 價值是w i 求解將哪些物品裝入揹包可使價值總和最大。所謂01揹包,表示每乙個物品只有乙個,要麼裝入,要麼不裝入。二 解決方案 考慮使用動態規劃求解,定義乙個遞迴式 opt i v 表示前i個物品,在揹包容量大小為v的情況下,最...