01
揹包題目描述
現有編號分別為
1 2 3 4 5
的五件物品,它們的重量分別是
2 2 6 5 4
,價值分別是
6 3 5 6 4
,現在給你個承重為
10的揹包,如何讓揹包裡裝入的物品具有最大的價值總和?
物品重量
w = ;
物品價值
v = ;
揹包容量為c;
假設opt[i][j]表示前i件物品放入容量為j的揹包中可獲得的最大價值,則對於第
i件物品來說,有兩種情況:
(1)
當w[i] > c
時,無法放入揹包,此時
opt[i][j] = opt[i-1][j];
(2)
當w[i] <= c
時,對於第
i件物品來說有兩種選擇:放入揹包或不放;
a. 不放:opt[i][j] = opt[i-1][j];前i
件物品可獲得的最大價值即是前
(i-1)
件物品放入容量為
j的揹包中獲得的最大價值;
b. 放入:opt[i][j] = opt[i-1][j-w[i]]+v[i];前i
件物品可獲得的最大價值即是前
(i-1)
件物品放入容量為
(j - w[i])
的揹包中獲得的最大價值加上第
i件物品的價值。
綜上,01揹包的狀態轉換方程如下:
**如下:
#include#include#includeusing namespace std;
int main()
} cout << opt[n][c] << endl;
return 0;
}
上述方法的時間複雜度和空間複雜度均為o(nc),其中空間複雜度是可以優化到o(c)的。由狀態轉換方程和狀態表可知,第i次迴圈得到的最大價值總和是由第(i-1)次迴圈遞推而來的;即:opt[i][j]是由opt[i-1][j]和opt[i-1][j-w[i]]+v[i]兩個子問題遞推得到的。要想得到opt[j] (揹包容量為j時可獲得的最大價值總和),則第二個for迴圈語句中我們需要讓j從容量c遞減至1的遞減順序來計算opt[j],這樣才能保證計算opt[j]時opt[j-w[i]]儲存的是狀態opt[i-1][j-w[i]]的值。(若還是讓j從1->n遞增,那麼前面的opt[j]會覆蓋計算後面的opt[j]值時前一次的狀態值)。
綜上,狀態轉換方程如下:
**如下:
#include#include#includeusing namespace std;
int main()
} cout << opt[c] << endl;
return 0;
}
動態規劃 01揹包
最優二叉查詢樹.cpp 定義控制台應用程式的入口點。01揹包問題。include stdafx.h include include define n 3 the number of real node define m 10 using namespace std int tmain int arg...
01揹包動態規劃
0 1揹包 問題描述 乙個旅行者有乙個最多能用 m公斤的揹包,現在有 n件物品,它們的重量 分別是w1,w2 wn,它們的價值分別為 c1,c2,cn.若每種物品只有一 件求旅行者能獲得最大總價值。輸入格式 w 第一行 兩個整數,m 揹包容量,m 200 和n 物品數量,n 30 w第2.n 1 行...
0 1揹包(動態規劃)
題意 有n件物品和乙個容量為v的揹包。第i件物品的體積是c i 價值是w i 求解將哪些物品裝入揹包可使價值總和最大。基本思路 這是最基礎的揹包問題,特點是 每種物品僅有一件,可以選擇放或不放。用子問題定義狀態 即f i v 表示前i件物品恰放入乙個容量為v的揹包可以獲得的最大價值。則其狀態轉移方程...