問題描述:
有 n 個重量和價值分別爲 w[i], v[i] 的物品。從這些物品中挑選出總重量不超過 W 的物品, 所求有挑選方案中價值中價值總和的最大值。
(限制條件:1 <= n <= 100, 1 <= w[i], v[i] <= 100, 1 <= W <= 10000)
輸入:
4 5 (n, W)
2 3 (w[i], v[i])
1 2
3 4
2 2
輸出:
7
每一件物品有兩種結果:放入或是不放入揹包。於是可以用搜索來解決。
但是這樣會產生高度爲 n 這樣大的遞歸樹,在限制的時間內會無法完成。看一下這樣產生的樹:
這樣的搜索會有重複調用,造成時間和空間上的浪費。
對於這種情況,可以採用動態規劃的方式解決。(動態規劃:把多階段過程轉化爲一系列單階段問題,利用各階段之間的關係,逐個求解)
從第i個物品開始挑選總重小於j時,總價值的最大值,其遞推式:
dp[n][j] = 0;
j < w[i] :
dp[i][j] = dp[i+1][j]
其他:
dp[i][j] = max( dp[ i+1 ][j] , dp[ i+1 ][ j-w[i] ] + v[i]
void fun()
{
for (int i = n-1; i >= 0; i--)
{
for (int j = 0; j <= W; j++)
{
if (j < w[i])
dp[i][j] = dp[i+1][j];
else
dp[i][j] = max(dp[i+1][j], dp[i+1][j-w[i]] + v[i]);
}
}
printf("%d\n", dp[0][W]);
}
參考書籍 :《挑戰程序設計競賽》