問題描述:
給定 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的情況下,最...