• 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];
        }
    };
    
  • 相关阅读:
    【转载】Highcharts一些属性
    What is assembly?
    用Apache配置Git服务器
    【转】.NET试题总结二
    【转】SVN服务器的快速搭建。
    【转】.NET试题总结一
    【转】国外C#开源系统一览表 ,C# Open Source
    Amazon S3 REST方式获取Object
    Action Filter
    a 标签 name 熟悉因为头部固定,导致置顶遮挡解决方案
  • 原文地址:https://www.cnblogs.com/libaoquan/p/7214554.html
Copyright © 2020-2023  润新知