0 1揹包問題

2022-08-05 10:30:13 字數 1786 閱讀 2840

01揹包問題:乙個揹包總容量為v,現在有n個物品,第i個 物品體積為weight[i],價值為value[i],現在往揹包裡面裝東西,怎麼裝能使揹包的內物品價值最大?

相信很多人拿到這道題的時候,立馬想到是不是用貪心去做,其實不是的。這道題,我們可以用gad的動態規劃來求解。那這樣的話找到動態轉移方程就成了解決此題的關鍵。我們來看看一組 :

如果你能將這個圖自己想清楚,那0-1揹包問題你也就弄得很明白了。

從下往上依次執行d(i,j)= max(d(i+1,j)d(i+1,j-w[i])+value[i])

首先:重量為5的物品在揹包容量為8的情況下只能是價值為6;

其次 :我們發現,如果把重量為4的物品拿進來,我們任然無法增加價值,因為揹包的容量不夠了;

再者 :又把重量為3的物品拿來,發現,當揹包容量為8的時候,可以放3和5物品,更新8容量的價值為8;

最後 : 最後看重量為2的物品,結果它還可以放2和5價值更大。

因此可以很容易的就推導出它的狀態轉移方程。

** :

#include #include 

#include

#include

const

int maxn = 101

;unsigned

intd[maxn][maxn];

using

namespace

std;

struct

node

th[maxn];

intmain()

printf(

"%d\n

", d[1][m]);//

最終輸出;

}

return0;

}

view code

上面這個**用的是正三角的形式,其實還有它的對稱的形式。它的狀態轉移方程為:d[i][j] = max(d[i - 1][j], d[i - 1][j - th[i].weight] + th[i].value)

#include #include 

#include

#include

const

int maxn = 101

;unsigned

intd[maxn][maxn];

using

namespace

std;

struct

node

th[maxn];

intmain()

printf(

"%d\n

", d[n][m]);

}return0;

}

view code

除此之外,這裡還可以更加的簡便。可以只用以為的陣列——滾動陣列。

memset(f, 0, sizeof

(f));

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

printf(

"%d\n

", f[m]);

view code

那你不經就想問了,為什麼可以這樣呢?我們之前的得到每乙個不同的物品時,新的價值都是從上乙個物品的價值上得到的,而我們在得到新的值得時候,做幾步複製

的操作,也就是沒有改變原價值的大小,只是最後判斷的時候,比較原有價值和可能的最大價值(這個價值也又

原價值陣列中的某個數加上該物品價值得到的),所以

做的而言,起作用的只是上乙個原有價值而已,打在處理的時候,我們要考慮,執行先後的問題,不然更新得情況會有錯誤。j需要逆序列舉。

例題 :飯卡

cow ehibition

揹包問題 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...