在n個物品中挑選若干物品裝入揹包,最多能裝多滿?假設揹包的大小爲m,每一個物品的大小爲A[i]html
注意事項
你不能夠將物品進行切割。數組
樣例
若是有4個物品[2, 3, 5, 7]
若是揹包的大小爲11,能夠選擇[2, 3, 5]裝入揹包,最多能夠裝滿10的空間。
若是揹包的大小爲12,能夠選擇[2, 3, 7]裝入揹包,最多能夠裝滿12的空間。
函數須要返回最多能裝滿的空間大小。函數挑戰
O(n x m) time and O(m) memory.
O(n x m) memory is also acceptable if you do not know how to optimize memory.優化標籤
動態規劃 揹包問題 LintCode 版權全部code
使用二維數組 dp[i][j] 記錄前 i 個數,在揹包大小爲 j 的條件下,最多能夠裝滿的空間
在僅有一個物品元素時,最多可裝滿的空間就是此物品大小(前提是揹包能夠裝下此物品)
有多個元素時,要裝入一個新元素,則最多能夠裝滿的空間就是裝入此元素前,揹包大小爲當前揹包大小-此元素大小的大小+此元素的大小(裝入新元素),或不變(未能裝下此元素)htm
也能夠解釋爲:blog
不放第i個物品:dp[i-1][j]
放第i個物品:那麼問題就轉化爲「前i-1件物品放入剩下的容量爲j-A[i]的揹包中」,此時能得到的最大致積就是dp[i-1][j-A[i]]再加上經過放入第i件物品得到的體積A[i]
轉自http://www.cnblogs.com/theskulls/p/5487061.htmlget
具體過程以下圖所示:
狀態轉移方程爲:dp[i][j] = max(dp[i - 1][j - A[i]] + A[i], dp[i - 1][j])it
class Solution { public: /** * http://www.lintcode.com/zh-cn/problem/backpack/-92-揹包問題 * @param m: An integer m denotes the size of a backpack * @param A: Given n items with size A[i] * @return: The maximum size */ int backPack(int m, vector<int> A) { // write your code here int size = A.size(), i = 0, j = 0; if(size <= 0) { return 0; } sort(A.begin(), A.end()); vector< vector<int> > dp(size, vector<int>(m+1, 0) ); for(i=0; i<size; i++) { for(j=1; j<=m; j++) { if(i==0 && j>=A[i]) { dp[i][j] = A[i]; } else if(i>0 && j>=A[i]){ dp[i][j] = (dp[i-1][j-A[i]] + A[i] > dp[i-1][j]) ? dp[i-1][j-A[i]] + A[i] : dp[i-1][j]; } else if(i>0 && j<A[i]){ dp[i][j] = dp[i-1][j]; } } } return dp[size-1][m]; } };
優化方法一的狀態方程,使用一維數組 dp[i] 記錄全部物品在揹包大小爲 j 的條件下,最多能夠裝滿的空間
在方法一中,二維數組的每一行僅僅與其上一行相關,因此能夠將二維數組壓縮成一維數組,能夠相成用二維數組的下一行將上一行覆蓋
由於新的結果要與其在二維素組中左上位置的元素比較(即一維數組中左邊的元素比較),因此從後向前遍歷一維數組,並寫入新元素
狀態轉移方程爲:dp[j] = max(dp[j], dp[j - A[i]] + A[i])io
class Solution { public: /** * @param m: An integer m denotes the size of a backpack * @param A: Given n items with size A[i] * @return: The maximum size */ int backPack(int m, vector<int> A) { // write your code here int size = A.size(), i = 0, j = 0; if(size <= 0) { return 0; } int *dp = new int[m+1]; for(i=0; i<m+1; i++) { dp[i] = 0; } for(i=0; i<size; i++) { for(j=m; j>=1; j--) { if(j >= A[i]) { dp[j] = (dp[j]>dp[j-A[i]] + A[i])?dp[j]:dp[j-A[i]] + A[i]; } } } return dp[m]; } };