lintcode:背包问题

背包问题

在n个物品中挑选若干物品装入背包,最多能装多满?假设背包的大小为m,每个物品的大小为A[i]

样例

如果有4个物品[2, 3, 5, 7]

如果背包的大小为11,可以选择[2, 3, 5]装入背包,最多可以装满10的空间。

如果背包的大小为12,可以选择[2, 3, 7]装入背包,最多可以装满12的空间。

函数需要返回最多能装满的空间大小。

解题

动态规划

这是最基础的背包问题,特点是:每种物品仅有一件,可以选择放或不放。

用子问题定义状态:即f[i][j]前i个物品放入大小为j的空间里能够占用的最大体积。

则其状态转移方程便是:

f[i][j]=max{f[i-1][j],f[i-1][j-A[i]]+A[i]}

不放第i个物品:f[i-1][j]

放第i个物品:那么问题就转化为“前i-1件物品放入剩下的容量为j-A[i]的背包中”,此时能获得的最大体积就是f[i-1][j-A[i]]再加上通过放入第i件物品获得的体积A[i]

注意上面的状态转移方程i的下标是从1开始的,下面程序是从0开始的,要适当调整

public class Solution {
    /**
     * @param m: An integer m denotes the size of a backpack
     * @param A: Given n items with size A[i]
     * @return: The maximum size
     */
    public int backPack(int m, int[] A) {
        // write your code here
        int[][] P = new int[A.length+1][m+1];
        for(int i = 1;i<= A.length; i++){
            for(int j = m;j>=0;j--){
                if(j>=A[i-1]){
                    P[i][j] = P[i-1][j-A[i-1]] + A[i-1];
                }
                P[i][j] = Math.max(P[i][j],P[i-1][j]);
            }
        }
        return P[A.length][m];
    }
}

或者对0的时候单独考虑

public class Solution {
    /**
     * @param m: An integer m denotes the size of a backpack
     * @param A: Given n items with size A[i]
     * @return: The maximum size
     */
    public int backPack(int m, int[] A) {
        // write your code here
        int[][] P = new int[A.length][m+1];
        for(int i = 0;i< A.length; i++){
            for(int j = m;j>=0;j--){
                if(i==0){ // 第0个物品可以放入空间为j的背包中,直接放入
                    if(j>=A[i])
                        P[i][j] = P[i][j-A[i]] + A[i];
                }else{
                    if(j>=A[i]){
                        P[i][j] = P[i-1][j-A[i]] + A[i];
                    }
                    P[i][j] = Math.max(P[i][j],P[i-1][j]);
                }

            }
        }
        return P[A.length-1][m];
    }
}

上面的时间空间复杂度都是O(MN)

状态转移方程式:

f[i][j] = Max(f[i-1][j],f[i-1][j-A[i]]+A[i])

f[i][j]表示对前i个物品,j的空间所能够取得的最大价值

实际上,我们需要求的是对所有的n个商品在m的空间中能够放入的最大价值

可以修改定义一个一维矩阵,长度就是m的空间的价值

f[j] = Max(f[j],f[j-A[i]]+A[i]) 这里就相当于对上面的矩阵进行了压缩

public class Solution {
    /**
     * @param m: An integer m denotes the size of a backpack
     * @param A: Given n items with size A[i]
     * @return: The maximum size
     */
    public int backPack(int m, int[] A) {
        // write your code here
        int[] P = new int[m+1];
        for(int i=0;i<A.length;i++){
            for(int j=m;j>=0;j--){
                if(j>=A[i])
                    P[j] = Math.max(P[j],P[j-A[i]] + A[i]);
            }
        }
        return P[m];
    }
}

参考:http://love-oriented.com/pack/P01.html

时间: 2024-10-17 22:46:40

lintcode:背包问题的相关文章

92 背包问题

原题网址:https://www.lintcode.com/problem/backpack/description 描述 在n个物品中挑选若干物品装入背包,最多能装多满?假设背包的大小为m,每个物品的大小为A[i] 你不可以将物品进行切割. 您在真实的面试中是否遇到过这个题?  是 样例 如果有4个物品[2, 3, 5, 7] 如果背包的大小为11,可以选择[2, 3, 5]装入背包,最多可以装满10的空间. 如果背包的大小为12,可以选择[2, 3, 7]装入背包,最多可以装满12的空间.

背包问题2 (lintcode)

这里: for(int j = 1;j <= m;j++) result[0][j] = 0x80000000; 不能从0开始,result[0][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 item

92.背包问题(lintcode)

注意j-A[i-1]必须大于等于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] * @return: The maximum size */ int backPack(int m, vector<int> A) { // write your code here int l

01背包问题-只求背包的最终最大价值,不考虑选哪些物品怎么放---最优解(欢迎讨论)

题目来自lintcode http://www.lintcode.com/zh-cn/problem/backpack/ 一个传统01背包问题的推广,假如只考一个背包放物品之后的最终最大价值,不考虑具体选哪些物品放入,该如何实现? 最蠢最笨的办法,那当然就是-老老实实的构造背包容量-物品矩阵,然后取出矩阵最上方最右的值即可: 代码也非常易懂: class Solution: # @param m: An integer m denotes the size of a backpack # @pa

九章算法面试题58 背包问题

九章算法官网-原文网址 http://www.jiuzhang.com/problem/58/ 题目 有一个大小为m(整数)的背包,和n个体积为正整数的物品(大小分别为A[i]).将这个n个物品选一些装到背包中,请问最多能装满多少的体积? 在线测试本题 http://www.lintcode.com/problem/backpack/ 解答 背包问题是动态规划问题的一种典型题目. 动态规划问题我们一般要考虑下面这四点. 1. 状态 State 2. 方程 Function 3. 初始化 Inti

九章算法面试题59 背包问题II

九章算法官网-原文网址 http://www.jiuzhang.com/problem/59/ 题目 有一个大小为m(整数)的背包,和n个体积(大小分别为A[i](整数))和价值(价格分别为B[i](整数))的物品.将这n个物品选一些装到背包中,请问能装价值最大为多少的物品? 在线测试本题 http://www.lintcode.com/en/problem/backpack-ii/ 解答 设F[i][j]为前i个物品,选一些组成j的体积,能够获得最大的价值是多少.状态转移方程:f[i][j]

动规基础——01背包问题(背包问题Ⅱ)

题目来源:领扣 | LintCode 有 i 个物品和一个总容量为 j 的背包. 给定数组 weight 表示每个物品的重量和数组 value 表示每个物品的价值,求最大价值.(物品不能分割) 背包问题II 这道题是一道动态规划(dp)算法的基础题,有两种实现方式,分别是递归和递推(迭代),前者比后者好理解. 解题思路 首先,题目的要求是找出最大价值,所以我们要想,怎么存放才能让他的价值最大呢?因为物品具有重量,背包容量也有限,所以我们不能每次都放入最大价值的物品,举个例子,假设背包容量为 10

[lintcode the-smallest-difference]最小差(python)

题目链接:http://www.lintcode.com/zh-cn/problem/the-smallest-difference/ 给定两个整数数组(第一个是数组 A,第二个是数组 B),在数组 A 中取 A[i],数组 B 中取 B[j],A[i] 和 B[j]两者的差越小越好(|A[i] - B[j]|).返回最小差. 排好序后用两个指针分别扫描两个数组,每次更新他们的差值的绝对值.并且依据他们两个数字的大小来决定谁来移动指针. 1 class Solution: 2 # @param

砝码问题之二(完全背包问题)

有一组砝码,重量互不相等,分别为m1.m2.m3……mn:每种砝码的数量有无限个. 现要用这些砝码去称物体的重量,给你一个重量n,请你判断有给定的砝码能否称出重量n. 现在给你一个正整数列表w和一个正整数n,列表w中的第i个元素w[i]表示第i种砝码的重量, n表示要你判断的重量.如果给定砝码能称出重量n,输出Yes,否则输出No. 例如,w=[2,5,11], n=9,则输出Yes(取两个2,一个5). w = [2, 5, 11] n = 9 S = [-1 for i in xrange(