lintcode-125-背包问题 II

125-背包问题 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?

标签

背包问题 动态规划 LintCode 版权所有

思路

采用动态规划,首先考虑使用二维数组 dp[i][j] 表示在前i件物品中选择若干件放在承重为 j 的背包中,可以取得的最大价值
动态转移方程为:
dp[i][j] = 0 (i0 || j0)
dp[i][j] = dp[i-1][j] (j < V[i])
dp[i][j] = max(dp[i-1][j-A[i-1]] + V[i-1], dp[i-1][j-1]) (j >= V[i])
过程如下

code

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

        for(i=0; i<size+1; i++) {
            for(j=0; j<m+1; j++) {
                if(i==0 || j==0){
                    dp[i][j] = 0;
                }
                else {
                    if(j >= A[i-1]){
                        dp[i][j] = (dp[i-1][j-A[i-1]]+V[i-1] > dp[i-1][j])?dp[i-1][j-A[i-1]]+V[i-1]:dp[i-1][j];
                    }
                    else{
                        dp[i][j] = dp[i-1][j];
                    }

                }
            }
        }

        display(dp);
        return dp[size][m];
    }
};

但是可以发现,当前 dp[i][j] 的取值仅仅和其上一行(左上角)元素有关,所以可以将二维数组 dp[i][j] 优化为 dp[j]

code

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

        for(i=0; i<size+1; i++) {
            for(j=m; j>=0; j--) {
                if(i==0 || j==0){
                    dp[j] = 0;
                }
                else {
                    if(j >= A[i-1]){
                        dp[j] = (dp[j-A[i-1]]+V[i-1] > dp[j])?dp[j-A[i-1]]+V[i-1]:dp[j];
                    }
                    else{
                        dp[j] = dp[j];
                    }

                }
            }
        }

        return dp[m];
    }
};
posted @ 2017-07-20 21:22  LiBaoquan  阅读(626)  评论(0编辑  收藏  举报