[LintCode] BackPack II

给出n个物品的体积A[i]和其价值V[i],将他们装入一个大小为m的背包,最多能装入的总价值有多大?

 注意事项

A[i], V[i], n, m均为整数。你不能将物品进行切分。你所挑选的物品总体积需要小于等于给定的m。

样例

对于物品体积[2, 3, 5, 7]和对应的价值[1, 5, 2, 4], 假设背包大小为10的话,最大能够装入的价值为9。

挑战 

O(n x m) memory is acceptable, can you do it in O(m) memory?

01背包问题的原始模型,利用二维数组进行求解。

空间复杂度O(n * m)

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) {
        // write your code here
        if (m == 0 || A.empty() || V.empty())
            return 0;
        vector<vector<int>> dp(A.size(), vector<int>(m + 1, 0));
        for (int j = 0; j != m + 1; j++) {
            if (j >= A[0])
                dp[0][j] = V[0];
        }
        for (int i = 1; i != A.size(); i++) {
            for (int j = 1; j != m + 1; j++) {
                if (j >= A[i])
                    dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - A[i]] + V[i]);
                else
                    dp[i][j] = dp[i - 1][j];
            }
        }
        return dp[A.size() - 1][m];
    }
};

将二维数组优化为一维数组,注意内层for循环逆序。

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) {
        // write your code here
        if (m == 0 || A.empty() || V.empty())
            return 0;
        vector<int> dp(m + 1, 0);
        for (int i = 0; i != A.size(); i++) {
            for (int j = m; j != 0; j--) {
                if (j >= A[i])
                    dp[j] = max(dp[j], dp[j - A[i]] + V[i]);
                else
                    dp[j] = dp[j];
            }
        }
        return dp[m];
    }
};

相关题目:

[LintCode] backPack I

posted @ 2017-08-25 20:27  immjc  阅读(135)  评论(0编辑  收藏  举报