• 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];
        }
    };
    
  • 相关阅读:
    记录------敬畏生活
    不错的博客分享
    Python学习笔记(一) 字符串和编码
    OSPF(二)基础实验 ASBR--- 在OSPF中引入自治系统外部路由--- LSA4和LSA5
    OSPF(一)基本概念和基础实验
    LAMP--PHP实验(四)使用包含文件提高代码效率
    LAMP--PHP实验(三)在页面之间传送变量 及遇到问题解决
    LAMP--PHP实验(二)常量和变量
    LAMP--PHP实验(一)第一个PHP程序
    随机获取图片的API
  • 原文地址:https://www.cnblogs.com/libaoquan/p/7214554.html
Copyright © 2020-2023  润新知