算法设计 - 01背包问题

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

学习来源

【自制】01背包问题算法动画讲解_哔哩哔哩_bilibili

问题描述

有N件物品,第i件物品的重量是w[i],价值是p[i]。

有一个背包,背包的承重是W。

求解:将哪些物品装入背包可获得最大价值。

实例说明

有如下物品,给定每件物品的重量和价值:

物品 重量 价值
葡萄 2 3
矿泉水 3 5
西瓜 4 6

有一个背包,承重是6。

请求出背包放入物品的最大价值。

01背包解题思路

01背包是基于动态规划解题的。

即将对承重6的背包的装载最大价值问题的求解,分解为对更小承重的背包的装载最大价值问题的求解。当分解到背包承重只有0时,就可以轻易得到背包装载最大价值为0。

同时,我们还需对物品的选择进行分解,将对多种物品的选择,分解更少种物品的选择,直到选择物品为0时,无论什么背包的装载最大价值都是0。

因此,我们可以得到一个二维矩阵图如下:

算法设计 - 01背包问题

其中:

  • 第0列表示背包承重为0,此时装不了任何物品,因此此背包的装载最大价值都为0。
  • 第0行表示背包不选择任何物品放入,因此无论什么背包,装载价值都为0。

算法设计 - 01背包问题

我们可以用dp二维数组来表示,行用i变量表示,列用j变量表示,因此:

  • dp[i][0] = 0
  • dp[0][j] = 0 

而dp[i][j]表示的含义是:背包承重为 j 的时候,选择物品范围 0~i 时,可以产生的最大价值。

下面我们讨论:背包承重为1时,只选0~1范围的物品,所能产生的最大价值,即求解dp[1][1],如下图标黄处所示

算法设计 - 01背包问题

此时,我们有两种选择:

  • 不选择第1行物品(即葡萄),只选择前面的物品,此时相当于 dp[1][1] = dp[0][1]
  • 选择第1行物品(即葡萄),但是由于葡萄重量为2 > 背包承重1,因此选不了,因此还是相当于 dp[1][1] = dp[0][1]

最终dp[1][1] = dp[0][1],

此时似乎还看不出状态转移方程,我们继续往后推导

算法设计 - 01背包问题

 接下来,我们扩大背包承重,即背包承重为2,此时依旧两种选择:

  • 不选择第1行物品(即葡萄),只选择前面的物品,此时相当于 dp[1][2] = dp[0][2]
  • 选择第1行物品(即葡萄),但是由于葡萄重量为2 = 背包承重2,因此可以选。接下来就是关键点了,背包装了葡萄后,还剩下0承重,那么0承重可以装什么呢?请看下面绿色标记

算法设计 - 01背包问题

我们发现,背包承重0时,不选葡萄的话(因为葡萄已经装入背包了,现在在讨论剩余承重的最大价值) 的最大价值是0。

因此,选了背包承重2,选了葡萄后能产生的最大价值为 3 + dp[0][0] = 3 + 0 = 3

而前面背包承重2,不选葡萄后能产生的最大价值继承自dp[0][2] = 0,

因此我们肯定选择装入葡萄,产生最大价值3。

算法设计 - 01背包问题

之后同理:背包承重3

如果不装葡萄,则最大价值继承自dp[0][3] = 0,

如果装入葡萄的话,葡萄产生价值3,剩余背包承重1,不选葡萄,能产生的最大价值为dp[0][1] = 0,因此装入葡萄的最大价值为3+0 = 3,

对比来看,背包承重3,装入葡萄产生的价值最大为3。

之后同理退出:背包承重4,5,6是否装入葡萄的最大价值

算法设计 - 01背包问题

下面继续扩大物品的选择,将矿泉水纳入选择范围,然后继续从背包承重1开始讨论:

背包承重1:

如果不选择矿泉水,那么产生的最大价值,继承自dp[1][1] = 0

如果选择矿泉水,则因为承重不够,装不了,因此也继承dp[1][1] = 0

算法设计 - 01背包问题

背包承重2:

如果不选择矿泉水,那么产生最大价值,继承自dp[1][2] = 3 

如果选择矿泉水,则因为承重不够,装不了,因此也继承dp[1][2] = 3

算法设计 - 01背包问题

背包承重3:

如果不选择矿泉水,那么产生最大价值,继承自dp[1][3] = 3 

如果选择矿泉水,则承重刚好,矿泉水价值5纳入,剩余承重0,选择不含矿泉水的物品的最大价值为dp[1][0] = 0,因此最后价值为 5 + 0 = 5

对比来看,选择矿泉水的最大价值更大。

背包承重4同理。

算法设计 - 01背包问题

我们来看看背包承重5:

如果不选择矿泉水,那么最大价值继承自dp[1][5] = 3

如果选择矿泉水,那么纳入矿泉水价值5,还剩余2承重,而2承重,不选矿泉水对应的最大价值为dp[1][2] = 3,因此总价值为8

对比来看,选择矿泉水的价值最大

算法设计 - 01背包问题

按此规则可以推导处后面所有dp

算法设计 - 01背包问题

状态转移方程

首先 dp[i][j] 表示:承重为 j 的背包,选择 0~i 范围的物品装入的最大价值。

其中 dp[i][0] = 0,dp[0][j] = 0

如果 i !== 0 && j !== 0,则

 dp[i][j] = Math.max(dp[i-1][j],   p[i] + dp[i-1][j - w[i]] )

状态转移方程中

  • dp[i-1][j] 表示 不选择物品 i 能产生的最大价值
  • p[i] + dp[i-1][j - w[i]] 表示  选择物品 i 后纳入了物品 i 的价值p[i],剩余承重为 j - w[i],其中w[i]是物品 i 的重量,而由于我们已经选择了物品 i ,因此剩余承重 j - w[i] 只能选择0~i-1范围物品,对应的最大价值为 dp[i-1][j - w[i]]

当然有一个优化动作就是:

如果背包承重放不下物品 i ,则该承重背包,只能从 0~i-1范围内选择商品,即直接继承dp[i-1][j]。

因此完整的状态转移方程为:文章来源地址https://www.toymoban.com/news/detail-404442.html

dp[i][0] = 0,
dp[0][j] = 0,
if(w[i] <= W) {
	dp[i][j] = Math.max(dp[i-1][j],   p[i] + dp[i-1][j - w[i]] )
} else {
	dp[i][j] = dp[i-1][j]
}

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

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

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

相关文章

  • 算法系列--动态规划--背包问题(1)--01背包介绍

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

    2024年04月16日
    浏览(37)
  • 回溯算法--01背包问题

    目录 回溯算法--01背包问题 [算法描述] [回溯法基本思想] 法一: 法二:  代码:  运行结果 代码改进  0-1背包问题是子集选取问题。一般情况下,0-1背包问题是NP完全问题。0-1背包问题的解空间可以用子集树表示。 解0-1背包问题的回溯法与解装载问题的回溯法十分相似。 在

    2023年04月09日
    浏览(26)
  • 算法训练第四十二天|01背包问题 二维 、01背包问题 一维、416. 分割等和子集

    视频链接:https://www.bilibili.com/video/BV1cg411g7Y6/ 参考:https://programmercarl.com/%E8%83%8C%E5%8C%85%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%8001%E8%83%8C%E5%8C%85-1.html 对于面试的话,其实掌握01背包,和完全背包,就够用了,最多可以再来一个多重背包。 而完全背包又是也是01背包稍作变化而来,即:完全

    2024年02月01日
    浏览(33)
  • 【算法5.1】背包问题 - 01背包 (至多最大价值、至少最小价值)

    目录 至少模板和至多模板的两大区别 1、至多模板 2、至少模板 2. 01背包 - 至多模板 - 体积至多j,总价值最大 1、朴素做法 - 二维dp  2、优化 - 一维dp 4700. 何以包邮? - 至少模板 - 价值至少j,总价值最小   初始化不同 : 至多模板求的是最大值,所以初始化为f[0~m]=0 至少模

    2024年02月12日
    浏览(26)
  • 算法套路十四——动态规划之背包问题:01背包、完全背包及各种变形

    如果对递归、记忆化搜索及动态规划的概念与关系不太理解,可以前往阅读算法套路十三——动态规划DP入门 背包DP介绍:https://oi-wiki.org/dp/knapsack/ 0-1背包:有n个物品,第i个物品的体积为w[i],价值为v[i],每个物品至多选一个, 求体积和不超过capacity时的最大价值和,其中i从

    2024年02月10日
    浏览(41)
  • 算法学习笔记(动态规划——01背包)

    先来聊聊动态规划,动态规划是分治法的一种体现,把一个问题分解成若干个子集,通过当前状态,经过操作得到下一个状态,最后得到最优问题解的一种方法。 步骤: 设定状态,保存状态 根据状态设定转移方程 确定边界 其中的01背包解决的是关于选择的动态规划问题,

    2024年03月25日
    浏览(40)
  • 【算法日志】动态规划刷题:01背包问题,多重背包问题(day37,day38)

    目录 前言 目标和(01背包) 一和零(01背包) 零钱兑换(多重背包) 排列总和(多重背包) 这两天都是背包问题,其中的01背包的一些应用问题需要一定的数学建模能力,需要i将实际问题简化成我们熟悉的背包问题;而这两天的多重背包问题还算比较基础,但也要我明白了

    2024年02月11日
    浏览(37)
  • 【Java实现】动态规划算法解决01背包问题

    1、问题描述: 一个旅行者有一个最多能装m公斤的背包,现在有n中物品,每件的重量分别是W1、W2、……、Wn,每件物品的价值分别为C1、C2、……、Cn, 需要将物品放入背包中,要怎么样放才能保证背包中物品的总价值最大? 2、动态规划算法的概述 1)动态规划(Dynamic Progra

    2023年04月09日
    浏览(36)
  • C++算法初级11——01背包问题(动态规划2)

    辰辰采药 辰辰是个天资聪颖的孩子,他的梦想是成为世界上最伟大的医师。为此,他想拜附近最有威望的医师为师。医师为了判断他的资质,给他出了一个难题。医师把他带到一个到处都是草药的山洞里对他说:“孩子,这个山洞里有一些不同的草药,采每一株都需要一些时

    2024年02月02日
    浏览(32)
  • 【算法】优先队列式分支限界法,以01背包问题为例

    题目链接:采药-洛谷 当洛谷上不让下载测试用例,可以试试:采药-ACWing 题目描述 辰辰是个天资聪颖的孩子,他的梦想是成为世界上最伟大的医师。为此,他想拜附近最有威望的医师为师。医师为了判断他的资质,给他出了一个难题。医师把他带到一个到处都是草药的山洞

    2024年02月02日
    浏览(32)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包