0 1揹包問題

2021-07-23 08:49:05 字數 1620 閱讀 2301

0-1揹包指的當往揹包裡裝物品是,要麼裝,要麼不裝,而不能裝物品的一部分;

部分揹包問題指的是可以裝物品的一部分,而不必做出0-1的二分選擇;

貪心演算法的關鍵所在是(貪心選擇性質和最優子結構);自上而下,乙個乙個的做出貪心選擇,不斷將問題規約到更小的子問題;

動態規劃的關鍵所在是(重疊子問題和最優子結構);自下而上,每一步都要做出選擇,但這些選擇依賴於子問題的解;

題目:總共有3件物品,揹包可容納5磅的東西,物品1重1磅價值60元,物品2重2磅,價值100元,物品3重3磅,價值為120元,怎麼才能最大化揹包所裝物品的價值?

我們假設:c[i]是第i件物品的重量,w[i]是第i件物品的價值,f[i][j]表示揹包總的重量為j時,可選物品為物品1~i,揹包能獲得的最大價值。

用動態規劃解0-1揹包問題,我麼從最小子問題開始求解,直到達到原問題的規模。最小子問題,我們知道,當揹包大小為0時,或者物品件數為0時,這時程式結束。所以,這些都是最小的子問題。下面來求出遞推公式,並給出dp表(儲存小問題的解,防止在計算大問題時帶來的重複計算的時間開銷)。

1、最終的遞推公式如下:

根據遞推公式填寫的dp**如下:

1、根據最小問題,我們進行逐個的狀態轉移。當物品個數為0時,那麼獲得的最大價值不論揹包有多大,那麼都為0,這就填寫了第1行;同理,當揹包的大小為0時,那麼不論物品有多重,那麼最終獲得的價值為0,這就填寫了第1列;

2、如果此時只放第1件物品,那麼當揹包的最大重量為1時,其獲得的最大價值為60,同理,當為2,3...5時,均為60,因為只有乙個物品;這就填寫了第2行;

3、當要放2件物品時,我們要判斷揹包的大小是否能容納的下2件物品;即第2件物品放還是不放。即有當j1、如果不放第i件物品,則問題轉化為前i-1件物品放入容量為j的揹包中;

2、如果放入第i件物品,則問題轉化為前i-1件放入剩餘的容量為j-c[i]的揹包中,此時能獲得的最大價值為f[i-1][j-c]i]]+w[i]。

#include#includeusing namespace std;

int main();

int w[4] = ;

/* int **dp = new int *[n + 1];

for (int i = 0; i < n + 1; i++)*/

int(*dp)[6] = new int[4][6];

//填dp表

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

for (int j = 1; j < v + 1; j++)

dp[0][0] = 0;

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

else

} }int result = dp[3][5];

cout << result << endl;

// for (int i = 0; i < 4; i++)

delete dp;

return 0;

}

揹包問題 01揹包問題

n個物品,總體積是v,每個物品的體積的vi,每個物品的最大價值是wi,在不超過v的體積下求最大價值 eg揹包容積為 5 物品數量為 4 物品的體積分別為 物品的價值分別為 思路定義乙個二位陣列int f new int n 1 v 1 f i j 就表示在1 i個物品中選取體積小於v的情況的最大價值...

揹包問題 01揹包

有n件物品和乙個容量為v的揹包。第i件物品的重量是c i 價值是w i 求解將哪些物品裝入揹包可使價值總和最大。01揹包中的 01 就是一種物品只有1件,你可以選擇放進去揹包即1,也可以選擇不放入揹包中即0。include include using namespace std const int ...

揹包問題(01揹包)

1085 揹包問題 在n件物品取出若干件放在容量為w的揹包裡,每件物品的體積為w1,w2 wn wi為整數 與之相對應的價值為p1,p2 pn pi為整數 求揹包能夠容納的最大價值。input 第1行,2個整數,n和w中間用空格隔開。n為物品的數量,w為揹包的容量。1 n 100,1 w 10000...