題目
有N種物品和一個容量為V的背包,每種物品都有無限件可用。第i種物品的費用是c[i],價值是w[i]。求解將哪些物品裝入背包可使這些物品的費用總和不超過背包容量,且價值總和最大。
完全背包按其思路仍然可以用一個二維數組來寫出:
f[i][v]=max{f[i-1][v-k*c[i]]+k*w[i]|0<=k*c[i]<=v}
同樣可以轉換成一維數組來表示:
偽代碼如下:




順序!
想必大家看出了和01背包的區別,這里的內循環是順序的,而01背包是逆序的。
現在關鍵的是考慮:為何完全背包可以這么寫?
在次我們先來回憶下,01背包逆序的原因?是為了是max中的兩項是前一狀態值,這就對了。
那么這里,我們順序寫,這里的max中的兩項當然就是當前狀態的值了,為何?
因為每種背包都是無限的。當我們把i從1到N循環時,f[v]表示容量為v在前i種背包時所得的價值,這里我們要添加的不是前一個背包,而是當前背包。所以我們要考慮的當然是當前狀態。
這里同樣給大家一道題目:
題目:http://acm.hdu.edu.cn/showproblem.php?pid=1114
代碼:http://www.cnblogs.com/William-xh/p/7339714.html
(分析代碼也是學習算法的一種途徑,有時並不一定要看算法分析,結合題目反而更容易理解。)
然后算完全背包時要注意:
- 求最大價值:要求恰好裝滿背包,那么在初始化時除了dp[0]為0其它dp[1..V]均設為-∞
- 求最小價值:要求恰好裝滿背包,那么在初始化時除了dp[0]為0其它dp[1..V]均設為∞
然后對於上面的那題,我在草稿紙上做了樣例(大家最好自己手動去畫畫),這樣大家可以更好地理解,為什么是順序的。(因為我們需要知道的是當前背包的狀態,而不是前一個)