01揹包問題

2021-07-28 19:54:40 字數 2573 閱讀 2102

n 件物品和乙個容量為

v的揹包。第

i 件物品的體積是ci

,其價值是wi

。求解,在不超過揹包容量情況下,將哪些物品裝入揹包可使價值總和最大。

這是最基礎的揹包問題,特點是:每種物品僅有一件。

狀態f[

i,v]

表示前i 件物品中選擇若干件放在容量為

v的揹包中,可以取得的最大價值。

轉移方程f[

i,v]

=max

對於第i 件物品,有放與不放兩種選擇。若選擇不放,f[

i,v]

=f[i

−1,v

];若選擇放,v−

ci確保有足夠的空間,隨之f[

i,v]

=f[i

−1,v

−ci]

+wi 。

/**

* * author 劉毅(limer)

* date 2017-03-17

* mode c++

*/#include#includeusing namespace std;

int main()

; //第i個物品的體積(下標從1開始)

int w[n + 1] = ; //第i個物品的價值

int f[n + 1][v + 1] = ; //狀態

for (int i = 1; i <= n; i++) //對於第i個物品

for (int v = 0; v <= v; v++)

cout << "最大價值是:"

<< f[n][v] << endl; //9

return

0;}

以上方法的時間和空間複雜度均為o(

vn) ,其中時間複雜度應該已經不能再優化了,但空間複雜度卻可以優化到o(

v)。

先考慮上面講的基本思路如何實現,肯定是有乙個主迴圈i ← 1 to n,每次算出來二維陣列f[

i,v]

的所有值。那麼,如果只用乙個陣列f[

v]能不能保證第

i 次迴圈結束後f[

v]中表示的就是我們定義的狀態f[

i,v]

呢? f[

i,v]

是由f[

i−1,

v]和f[i

−1,v

−ci]

兩個子問題遞推而來,能否保證在推f[

i,v]

時(也即在第

i 次主迴圈中推f[

v]時)能夠取用f[

i−1,

v]和f[i

−1,v

−ci]

的值呢?

事實上,這要求在每次主迴圈中我們以v ← v to c[i]的遞減順序計算f[

v],這樣才能保證計算f[

v]時f[v

−ci]

儲存的是狀態f[

i−1,

v−ci

] 的值。

優化後的**如下:

/**

* * author 劉毅(limer)

* data 2017-03-17

* mode c++

*/#include#includeusing namespace std;

int main()

; //第i個物品的體積(下標從1開始)

int w[n + 1] = ; //第i個物品的價值

int f[v + 1] = ; //狀態

for (int i = 1; i <= n; i++) //對於第i個物品

for (int v = v; v >= c[i]; v--)

f[v] = max(f[v], f[v - c[i]] + w[i]);

cout << "最大價值是:"

<< f[v] << endl; //9

return

0;}

我們看到的求最優解的揹包問題題目中,事實上有兩種不太相同的問法。有的題目要求「恰好裝滿揹包」時的最優解,有的題目則並沒有要求必須把揹包裝滿。這兩種問法的實現方法只是在初始化的時候有所不同。

如果是第一種問法,要求恰好裝滿揹包,那麼在初始化時除了f[0]為0,其它f[1]…f[v]均設為−∞,這樣就可以保證最終得到的f[v]是一種恰好裝滿揹包的最優解。如果並沒有要求必須把揹包裝滿,而是只希望**盡量大,初始化時應該將f[0]…f[v]全部設為0。

這是為什麼呢?可以這樣理解:初始化的f陣列事實上就是在沒有任何物品可以放入揹包時的合法狀態。如果要求揹包恰好裝滿,那麼此時只有容量為0的揹包可以在什麼也不裝且價值為0的情況下被「恰好裝滿」,其它容量的揹包均沒有合法的解,屬於未定義的狀態,應該被賦值為-∞了。如果揹包並非必須被裝滿,那麼任何容量的揹包都有乙個合法解「什麼都不裝」,這個解的價值為0,所以初始時狀態的值也就全部為0了。

[ 1 ] .揹包九講.

文章**我的個人部落格:

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