动态规划01背包问题

这篇具有很好参考价值的文章主要介绍了动态规划01背包问题。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

01背包问题

假设你是一名经验丰富的探险家,背着背包来到野外进行日常探险。天气晴朗而不燥热,山间的风夹杂着花香,正当你欣赏这世外桃源般的美景时,突然,你发现了一个洞穴,这个洞穴外表看起来其貌不扬,但凭借着惊为天人的直觉,这个洞穴不简单。于是,你开始往洞穴内探索,希望能发现一些有意思的东西。终于,皇天不负有心人,你在洞穴的尽头,发现了一堆珠宝,凭借你惊人的阅历,一眼便看出了它们各自的价值,心想着下下下下下下下下半辈子都有着落了。然而,天有不测风云,正准备将它们收入囊中,却不小心触碰到一个防御机关,洞穴马上就要崩塌了。在此危机时刻,你只有一个背包,你必须尽快做出抉择,从中选择最值钱的珠宝塞到你的背包,让背包中珠宝的总价值最大。好了好了,啰里啰嗦了大半天,我还是来精简一下问题吧。简而言之,你只有一个容量有限的背包,总容量为c,有n个可待选择的物品,每个物品只有一件,它们都有各自的重量和价值,你需要从中选择合适的组合来使得你背包中的物品总价值最大。问题分析:那还不简单,不管是什么,先往背包里塞,塞满赶紧走,狗命要紧,狗命要紧。。。好了好了,开个玩笑,言归正传。简单起见,我们来将上面的问题具体化,举一个更具体的栗子:假设有4个物品,它们的价值(v)和重量(w)如下图:
动态规划01背包问题
背包总容量为10,现在要从中选择物品装入背包中,要求物品的重量不能超过背包的容量,并且最后放在背包中物品的总价值最大。emmm,等等,为什么叫做0/1背包呢?为什么不叫1/2背包,2/3背包???仔细想想,这里每个物品只有一个,对于每个物品而言,只有两种选择,盘它或者不盘,盘它记为1,不盘记为0,我们不能将物品进行分割,比如只拿半个是不允许的。这就是这个问题被称为0/1背包问题的原因。所以究竟选还是不选,这是个问题。让我们先来体验一下将珠宝装入背包的感觉,为了方便起见,用xi代表第i个珠宝的选择(xi = 1 代表选择该珠宝,0则代表不选),vi代表第i个珠宝的价值,wi代表第i个珠宝的重量。于是我们就有了这样的限制条件:
动态规划01背包问题
我们的初始状态是背包容量为10,背包内物品总价值为0,接下来,我们就要开始做选择了。对于1号珠宝,当前容量为10,容纳它的重量2绰绰有余,因此有两种选择,选它或者不选。我们选择一个珠宝的时候,背包的容量会减少,但是里面的物品总价值会增加。就像下面这样:
动态规划01背包问题
这样就分出了两种情况,我们继续进行选择,如果我们选择了珠宝1,那么对于珠宝2,当前剩余容量为8,大于珠宝2的容量3,因此也有两种选择,选或者不选。
动态规划01背包问题
现在,我们得到了四个可能结果,我们每做出一个选择,就会将上面的每一种可能分裂成两种可能,后续的选择也是如此,最终,我们会得到如下的一张决策图:
动态规划01背包问题
这里被涂上色的方框代表我们的最终待选结果,本来应该有16个待选结果,但有三个结果由于容量不足以容纳下最后一个珠宝,所以就没有继续进行裂变。然后,我们从这些结果中,找出价值最大的那个,也就是13,这就是我们的最优选择,根据这个选择,依次找到它的所有路径,便可以知道该选哪几个珠宝,最终结果是:珠宝4,珠宝2,珠宝1。简单的看,对于每个物品,无外乎两种可能:选,或者不选。不选的话,背包的容量不变,最大价值还是之前的价值;选的话,背包的容量变小,价值变大。最优方案就是比较这两种方案,哪个会更好些:
**

01背包问题

[算法分析]

定义状态∶dp[i][j]:有i件物品,背包容量为j的情况下存储的最大价值w[i]第i件物品的重量,c背包总容量,j表示背包实时容量,也就是0到c之间的容量,v[i]第i件物品的价值如果w[i]>j:放不下,最大价值为i-1件物品讨论时的最大价值,即dp[i-1][j];如果w[i]<=j:放得下:
选上: 剩余容量:j-w[i],最大价值:v[i] + (i-1件物品,容量在j- w[i]的情况下最大价值),即v[i]+dp[i-1][j-w[i]];不选: 最大价值:i-1件物品讨论时的最大价值,即dp[i-1][j];所以动态转移方程:dp[i][j]=max(dp[i-1][j],v[i]+dp[i-1][j-w[i]])


```cpp
#include<bits/stdc++.h>
using namespace std;
/*
动态转移方程:dp[i][j]=max(dp[i-1][j],v[i]+dp[i-1][j-w[i]]) 
*/
//c代表背包容量
//dp[i][j]:有i件物品,背包容量为j的情况下存储的最大价值
int c,dp[40][210],w[40],v[40],i,j,n; 
int main(){
    cin >> c>>n;
    for(i=1;i<=n;i++){
        cin >> w[i]>>v[i];
    }
    //递推求dp数组
    for(i=1;i<=n;i++){
        //在i件物品,讨论背包容量j分别是1-c的情况下,最大价值
        //j代表背包容量
        for(j=1;j<=c;j++){
            //如果能够放得下
            if(w[i]<=j){
                dp[i][j]=max(dp[i-1][j],v[i]+dp[i-1][j-w[i]]);
            } else{
                //放不下
                dp[i][j]=dp[i-1][j]; 
            }
        }   
    } 
    cout << dp[n][c];
    return 0;
}


背包

有个背包可承受重量N,现有T件物品,每件物品重量为wi​,价值为vi​,每件物品只有一个,这个背包可以装载物品的最大价值是多少?输入格式第一行,两个整数,分别表示N和T,用空格隔开(N≤1000,T≤100)接下来T行,每行两个整数,分别表示T件物品的重量wi​和价值vi​(1≤wi​,vi​≤100)输出格式一行,表示这个背包可以装载物品的最大价值输入输出样列
输入样例1:
100 577 9222 2229 8750 4699 90
输出样例1:

133

[算法分析]定义状态∶d(i,j)表示为前i个物品分配j容量的背包,可以获得的最大价值。对于物品i有2种选择∶选择1∶ 不选择将i放入背包∶ d(i, j) = d(i-1,j)。选择2∶选择将i放入背包d(i,j)=d(i-1,j-wi​)+vi​(j>=wi​)。状态转移方程∶ d(i,j)= max(d(i-1,j), d(i-1,j-wi​)+vi​)。

#include<bits/stdc++.h>
using namespace std;
const int N=1005,T=105;
//dp[i][j]:有i件物品,背包容量为j的情况下存储的最大价值
int dp[T][N],v[T],w[T];
int main()
{
    int n,t;
    cin>>n>>t;
    for(int i=1;i<=t;i++)
    {
        cin>>w[i]>>v[i];
    }
    for(int i=1;i<=t;i++)  //t件物品
    {
        for(int j=1;j<=n;j++) 
        //在i件物品,讨论背包容量j分别是1-n的情况下,最大价值
        //j代表背包容量
        {
            if(j>=w[i])//放得下
                dp[i][j]=max(dp[i-1][j],v[i]+dp[i-1][j-w[i]]);
            else//放不下
                dp[i][j]=dp[i-1][j];
        }
    }
    cout<<dp[t][n];
    return 0;
} 

————未完

一定拖更

动态规划01背包问题

好了,背包问题(1·)就到这——别走第二期动态规划下期更新!!!o( ̄▽ ̄)d

播放量到150下期继续

不见不散文章来源地址https://www.toymoban.com/news/detail-456544.html

到了这里,关于动态规划01背包问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 动态规划01背包问题

    假设你是一名经验丰富的探险家,背着背包来到野外进行日常探险。天气晴朗而不燥热,山间的风夹杂着花香,正当你欣赏这世外桃源般的美景时,突然,你发现了一个洞穴,这个洞穴外表看起来其貌不扬,但凭借着惊为天人的直觉,这个洞穴不简单。于是,你开始往洞穴内

    2024年02月06日
    浏览(30)
  • 动态规划:01背包问题(二)

    上篇博客动态规划:01背包问题(一)将的是用二维数组来解决,而本篇博客就是把二维dp数组降为一维dp数组(滚动数组)在使用二维数组的时候,递推公式:dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]); 其实可以发现如果 把dp[i - 1]那一层拷贝到dp[i]上 ,表达式完全可以是

    2024年01月22日
    浏览(47)
  • 动态规划——01背包问题

    由于本人实力尚浅,接触算法没多久,写这篇blog仅仅是想要提升自己对算法的理解,如果各位读者发现什么错误,恳请指正,希望和大家一起进步。(●’◡’●) 状态表示 :用一个数组 f[][] (数组可能是一维也可能是二维,根据具体题目具体分析)来表示某个集合,这个集合

    2024年02月03日
    浏览(33)
  • 算法系列--动态规划--背包问题(1)--01背包介绍

    💕\\\"趁着年轻,做一些比较cool的事情\\\"💕 作者:Lvzi 文章主要内容:算法系列–动态规划–背包问题(1)–01背包介绍 大家好,今天为大家带来的是 算法系列--动态规划--背包问题(1)--01背包介绍 背包问题是动态规划中经典的一类问题,经常在笔试面试中出现,是非常 具有区分度 的题

    2024年04月16日
    浏览(37)
  • C++ 动态规划 01背包问题

    有 N 件物品和一个容量是 V 的背包。每件物品只能使用一次。 第 i 件物品的体积是 vi ,价值是 wi 。 求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。 输出最大价值。 输入格式 第一行两个整数, N,V ,用空格隔开,分别表示物品数量和背

    2024年04月27日
    浏览(26)
  • 动态规划—— 01背包问题(一维,二维)

    0-1背包问题是一个经典问题,特别是在算法和动态规划领域。问题是关于一个小偷,他有一个可以携带最大重量的背包,并且他有一组物品,其中每个物品都有自己的价值和重量。小偷希望在不超过背包所能承载的最大重量的情况下,最大化他从这些物品中获得的总价值。问

    2024年02月19日
    浏览(36)
  • 01背包问题(动态规划)(详细图解)

    目录 题目: 题解: 图表解析:  详细例子: 有 N 件物品和一个容量是 V 的背包。每件物品只能使用一次。 第 i 件物品的积是 vi,价值是 wi。 求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。 输出最大价值。 输入格式: 第一行两个整

    2024年02月03日
    浏览(30)
  • 动态规划-01背包问题(python)

    对于动态规划问题,就是牺牲空间来提高时间,通过将一个个小问题的答案存储起来,直接供给后面问题求解,避免重复的运算,从而提高效率,这就是动态规划的思想。 下面我们通过一个经典的01背包问题来了解动态规划的解题方法吧(文末附上完整代码) 首先,将每个物

    2024年02月06日
    浏览(34)
  • 动态规划母题:01背包问题

    动态规划与图论,前缀和与差分等有模板的算法不同,动态规划更考察思维能力,而不是运用模板的能力。 个人认为 Acwing 关于动态规划的讲解比较容易理解。我会根据 Acwing 的动态规划解题思路来讲解题目。 虽说动态规划没有固定的模板,但是还是有相对固定的套路。但

    2024年02月12日
    浏览(56)
  • [动态规划] 01背包问题及其优化

    题目描述 给一个能承重V的背包,和n件物品,我们用重量和价值的二元组来表示一个物品,第i件物品表示为(Vi,Wi),问:在背包不超重的情况下,得到物品的最大价值是多少? 输入 第一行输入两个数 V,n,分别代表背包的最大承重和物品数。 接下来n行,每行两个数Vi,W

    2024年02月03日
    浏览(32)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包