有
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...