lintcode-92-揹包問題

92-揹包問題

在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

方法一(空間複雜度O(n x m) )

使用二維數組 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

code

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];
    }
};

方法二(空間複雜度 O(m) )

優化方法一的狀態方程,使用一維數組 dp[i] 記錄全部物品在揹包大小爲 j 的條件下,最多能夠裝滿的空間
在方法一中,二維數組的每一行僅僅與其上一行相關,因此能夠將二維數組壓縮成一維數組,能夠相成用二維數組的下一行將上一行覆蓋
由於新的結果要與其在二維素組中左上位置的元素比較(即一維數組中左邊的元素比較),因此從後向前遍歷一維數組,並寫入新元素
狀態轉移方程爲:dp[j] = max(dp[j], dp[j - A[i]] + A[i])io

code

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];
    }
};
相關文章
相關標籤/搜索