LintCode 125: Backpack II (0-1背包问题, DP经典)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/roufoo/article/details/83048236

本文参考了九章的背包教程:

解法1:
经典DP解法。
时间复杂度O(MN),空间复杂度O(MN)。
注意:dp[m+1][n+1],如果定义成dp[m][n],dp[0][]就有歧义:到底表示不取任何包,还是取包0呢?

class Solution {
public:
    /**
     * @param m: An integer m denotes the size of a backpack
     * @param A: Given n items with size A[i]
     * @param V: Given n items with value V[i]
     * @return: The maximum value
     */
    int backPackII(int m, vector<int> &A, vector<int> &V) {
        int itemCount = A.size();
        //dp[itemCount][packSize]
        vector<vector<int>> dp(itemCount + 1, vector<int>(m + 1, 0));
        
        for (int i = 1; i <= itemCount; ++i) {
            for (int j = 0; j <= m; ++j) {
                dp[i][j] = dp[i - 1][j];
                if (j >= A[i - 1]) {
                    dp[i][j] = max(dp[i][j], dp[i - 1][j - A[i - 1]] + V[i - 1]);
                }
                    
            }
        }        
        return dp[itemCount][m];
    }
};

解法2:
在解法1的基础上加上滚动数组优化
时间复杂度O(MN)
空间复杂度O(N)

class Solution {
public:
    /**
     * @param m: An integer m denotes the size of a backpack
     * @param A: Given n items with size A[i]
     * @param V: Given n items with value V[i]
     * @return: The maximum value
     */
    int backPackII(int m, vector<int> &A, vector<int> &V) {
        int itemCount = A.size();
        //dp[2][packSize]
        vector<vector<int>> dp(2, vector<int>(m + 1, 0));
        int rotate = 0;
        
        for (int i = 0; i <= itemCount; ++i) {
            rotate ^= 1;
            for (int j = 0; j <= m; ++j) {
                dp[rotate][j] = dp[rotate ^ 1][j];
                if (j >= A[i - 1]) {
                    dp[rotate][j] = max(dp[rotate][j], dp[rotate ^ 1][j - A[i - 1]] + V[i - 1]);
                }
            }
        }
        
        return dp[rotate][m];
    }
};

解法3:
将第2层循环倒序,因为i时候的dp[j - A[i - 1]]实际上就是i-1时候的dp[j - A[i - 1]],因为倒序的时候,dp[j]更新了,此时dp[j - A[i - 1]]还未更新。
时间复杂度还是O(MN)。
空间复杂度还是O(N)。但只用了一个一维数组。

class Solution {
public:
    /**
     * @param m: An integer m denotes the size of a backpack
     * @param A: Given n items with size A[i]
     * @param V: Given n items with value V[i]
     * @return: The maximum value
     */
    int backPackII(int m, vector<int> &A, vector<int> &V) {
        int itemCount = A.size();
        //dp[packSize]
        vector<int> dp(m + 1, 0);
        
        for (int i = 1; i <= itemCount; ++i) {
            for (int j = m; j >= A[i - 1]; --j) {
                dp[j] = max(dp[j], dp[j - A[i - 1]] + V[i - 1]);
            }
        }
        
        return dp[m];
    }
};

猜你喜欢

转载自blog.csdn.net/roufoo/article/details/83048236