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的空间。

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

挑战

O(n x m) time and O(m) memory.

O(n x m) memory is also acceptable if you do not know how to optimize memory.

标签

背包问题

LintCode 版权所有

动态规划(DP)

思路:

背包问题是动态规划的一种题型,它的特点如下:

1. 用值作为dp维度
2. dp过程就是填写矩阵
3. 可以用滚动数组进行优化  转自此文

dp【i】【j】表示前 i 个物品放到容量为 j 的背包里能够占用的最大体积。

状态转移方程为:dp【i】【j】= max(dp【i-1】【j】,dp【i-1】【j-A【i】】+A【i】)。

每个物品只有两种状态,放或者不放。对于容量为 j 的背包,放入第 i-1 件物品后占用的最大体积为dp【i-1】【j】,现在考虑第 i 件物品。

不放,dp【i】【j】=dp【i-1】【j】;

放,需要从 j 中腾出A【i】的空间,再看剩余的空间放前 i-1 件物品最大能占多少空间,即dp【i】【j】=A【i】+ dp【i-1】【j-A【i】】。(注意前提是 j >= A【i】)

最后的dp【i】【j】就是上述两种情况的较大值。

AC代码:

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
    if (A.empty())
    {
        return 0;
    }
    int size=A.size();
    vector<vector<int>> dp(size,vector<int>(m+1,0));
    //初始化第一行,即只有第一个物品时,若背包容量大于等于A[0],放物品能占用的最大空间为A[0];
    for (int j=0;j<=m;j++)
    {
        if (j>=A[0])
        {
            dp[0][j]=A[0];
        }
    }
    //计算dp其他元素;
    for (int i=1;i<size;i++)
    {
        for (int j=0;j<=m;j++)
        {
            if (j>=A[i])//能放A[i],计算此时的最大体积,注意是大于等于;
            {
                dp[i][j]=dp[i-1][j-A[i]]+A[i];
            }
            dp[i][j]=max(dp[i-1][j],dp[i][j]);
        }
    }
    return dp[size-1][m];
    }
};

PS:状态转移方程简而言之就是,背包容量为 j 时,能放得下 i 就腾出A【i】的空间,再看剩余的空间放前 i-1 件物品最大能占多少空间,二者之和与不放 i 能占用的最大体积比,哪个大就取哪个;放不下就直接看0~i-1能占用 j 的最大容量是多少;

参考:

lintcode backpack 背包问题

lintcode:背包问题

【LintCode】Backpack 背包问题

LintCode背包问题总结  总结了一系列背包问题,可以好好参考。

原文地址:https://www.cnblogs.com/Tang-tangt/p/9374818.html

时间: 2024-10-09 00:14:14

92 背包问题的相关文章

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

桌艘仁涛辽od8r81udljby2eb8n

http://www.qiushibaike.com/tag/%e9%82%a2%e5%8f%b0%e8%bf%b7%e5%a5%b8%e8%8d%af%e5%93%aa%e9%87%8c%e6%9c%89%e5%8d%96%2b%ef%bd%91%ef%bc%92%ef%bc%98%ef%bc%95%ef%bc%98%ef%bc%92%ef%bc%99%ef%bc%91%ef%bc%92%ef%bc%90.http://www.gxxc.gov.cn/Town/TownDetails?id=9

廴俏士芡芍o55o536zc6571gynd

http://www.gxxc.gov.cn/Town/TownDetails?id=94210&town=%e5%85%b4%e5%9f%8e%e5%93%aa%e9%87%8c%e6%9c%89%e6%b0%b0%e5%8c%96%e9%92%a0%e4%b9%b0%2b%ef%bd%91Q%e2%92%89%e2%92%8f%e2%92%8c%e2%92%8f%e2%92%89%e2%92%90%e2%92%88%e2%92%89O.http://www.qiushibaike.com/t

米胖涡壤糖r0kgjk681iwv9bnnmnd

http://www.qiushibaike.com/tag/%e6%99%8b%e5%b7%9e%e5%93%aa%e9%87%8c%e6%9c%89%e8%bf%b7%e5%b9%bb%e8%8d%af%e5%8d%96%2b%ef%bd%91%ef%bc%92%ef%bc%98%ef%bc%95%ef%bc%98%ef%bc%92%ef%bc%99%ef%bc%91%ef%bc%92%ef%bc%90.http://www.qiushibaike.com/tag/%e6%95%a6%e5%

沂腾烫扣刻az7a1ij0002mi

http://www.qiushibaike.com/tag/%e6%b2%85%e6%b1%9f%e5%93%aa%e9%87%8c%e6%9c%89%e6%b0%b0%e5%8c%96%e9%92%be%e5%8d%96%2b%ef%bd%91%ef%bc%92%ef%bc%98%ef%bc%95%ef%bc%98%ef%bc%92%ef%bc%99%ef%bc%91%ef%bc%92%ef%bc%90.http://www.qiushibaike.com/tag/%e6%97%a0%e6%

[C++11][算法][穷举]输出背包问题的所有可满足解

关于背包问题的题目,前人之述备矣,这里只讨论实现 输入: n ca w_1 v_1 w_2 v_2 ... w_n v_n 其中,n是物品总数,ca是背包大小,w_n是第n个物品的重量,v_n是第n个物品的价值 输出: v_1 x v_2 x v_3 x ... 其中,v_n是当前情况为x时背包的价值,x是一串序列,由0,1组成,表示是否放入背包 如: 1001就表示第一个和最后一个物品放入背包,中间两个物品不放入 要求编写一个程序,输出所有可满足解. 思路很简单,就是穷举.穷举每一个情况. 伪

利用回溯法求解背包问题

最近看完了利用回溯法求八皇后问题,最后成功求解到92种解法,然后在看利用贪心求解背包问题,突然想到其实也可以利用回溯法求解背包问题,本质上回溯法是一个穷举的方式在求. 回溯法求解出的结果肯定是正确的,这也可以验证自己所写的贪心算法的正确性. 问题描诉: 设定Wmax为最大重量,W[](0~n-1)为编号0~n-1的货物重量,V[](0~n-1)为其价值,x[]为其中解, 在wn=ΣXi*Wi<Wmax的条件下,求Vmax=ΣXi*Vi. 代码如下: //全局变量最大价值int maxvalue=

hdu 5677 ztr loves substring(manacher,背包问题)

1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 5 /** 6 7 8 manacher 处理出回文串长度 9 p[i]:半径 10 11 if(s[i] == '#' && p[i] == 1) continue; 12 else{ 13 int tmp = p[i] / 2; 14 if(s[i] == '#') for(int i = 2 ; i <= tmp ;

贪心算法练习题:部分背包问题

/*----------------------------------------------------- 有n个物体,第i个物体的重量是wi,价值为vi, 选若干个物体,使得在总重量不超过c的情况下让总价值尽量高. 这里每个物体都可以只取走一部分,价值和重量按比例计算. 输入: 第一行输入两个整数表示n和c. 第2到第n+1行每行两个整数分别表示wi和vi. 输出: 第一行输出所选物品的总价值v和总重量w以及所选物品的种类数num.两两之间用空格分隔. 第二行到第n+1行按照输入物品的顺序