1. 程式人生 > >LintCode 440: Backpack III (完全揹包問題,DP經典)

LintCode 440: Backpack III (完全揹包問題,DP經典)

解法1: 將其視為多重揹包變形,每種物品取的上限是m/A[i]。 時間複雜度: O(sum(m/A[i]) * backpackSize)。 空間複雜度: O(m)。

class Solution {
public:
    /**
     * @param A: an integer array   // size array
     * @param V: an integer array   // value array
     * @param m: An integer         // backpack size
     * @return: an array
     */
    int backPackIII(vector<int> &A, vector<int> &V, int m) {
        int n = A.size();
        vector<int> dp(m + 1, 0);
        
        for (int i = 1; i <= n; ++i) {
            
            for (int j = 1; j * A[i - 1] <= m; ++j) {  //j can start from 0 or 1
                
                for (int k = m; k >= A[i - 1]; --k) {
                    
                    dp[k] = max(dp[k], dp[k - A[i - 1]] + V[i - 1]);
                }
            }
        }
        
        return dp[m];
    }
};

// The following code is also OK. A[i - 1] to A[i]
#if 0
    int backPackIII(vector<int> &A, vector<int> &V, int m) {
        int n = A.size();
        vector<int> dp(m + 1, 0);
        
        for (int i = 0; i < n; ++i) {
            
            for (int j = 1; j * A[i] <= m; ++j) {  //j can start from 0 or 1
                
                for (int k = m; k >= A[i]; --k) {
                    
                    dp[k] = max(dp[k], dp[k - A[i]] + V[i]);
                }
            }
        }
        
        return dp[m];
    }
#endif

解法2: 3重迴圈變2重迴圈。 時間複雜度O(mn),空間複雜度O(m)。

    int backPackIII(vector<int> &A, vector<int> &V, int m) {
        int n = A.size();
        vector<int> dp(m + 1, 0);
        
        for (int i = 0; i < n; ++i) {
            
        //    for (int j = 1; j * A[i] <= m; ++j) {
                //for (int k = m; k >= A[i]; --k) {
                for (int k = A[i]; k <= m; ++k) {    
                    dp[k] = max(dp[k], dp[k - A[i]] + V[i]);
                }
        //    }
        }
        
        return dp[m];
    }