当前位置: 首页 > news >正文

0 1背包的解释 这个代码解释风格好

好的,没问题。我们从零开始,忘记所有术语,只看这个问题的本质。

0. 问题的本质是什么?

想象你有一个背包,它能装的东西有限(容量为5)。
你面前有一堆宝贝,每个宝贝都有自己的重量价值

  • 宝贝A:重1,值6
  • 宝贝B:重2,值10
  • 宝贝C:重3,值12

你面临一个选择:要拿哪个宝贝,才能让背包里的总价值最高

每个宝贝你只能拿一次,这就是“0-1背包”的“0-1”——要么拿(1),要么不拿(0)。


1. 为什么不能“贪心”?

“贪心”就是你觉得哪个最划算就先拿哪个。比如你可能会想:

  • 宝贝A:价值/重量 = 6/1 = 6
  • 宝贝B:价值/重量 = 10/2 = 5
  • 宝贝C:价值/重量 = 12/3 = 4

你可能会先拿宝贝A(最划算),然后背包容量还剩4,再拿宝贝B(次划算),背包容量还剩2,装不进宝贝C了。总价值是 6 + 10 = 16。

但更好的方案是:拿宝贝B和宝贝C,总重量是2+3=5,正好装满,总价值是10+12=22。

所以,简单的贪心算法是错的。我们需要一个更强大的方法,能考虑所有可能性,但又不会太慢。这个方法就是动态规划


2. 动态规划的定义和逻辑

动态规划就像一个“填表格”的游戏。我们不是直接寻找最终答案,而是一步一步地,有条理地解决一个个小问题,最后从小问题的答案里推导出最终的答案。

我们来定义这个表格(二维数组 dp):

dp[i][j] 的意思是:“只考虑前 i 个宝贝,在背包容量为 j 的情况下,能得到的最大价值。”

我们的最终目标,就是要填完整个表格,找到 dp[3][5] 的值(因为有3个宝贝,背包容量是5),这个值就是最终答案。


3. 如何一步步填表格?

我们用你提供的测试数据来填这个 dp 表格。

  • 宝贝:A(1,6), B(2,10), C(3,12)
  • 背包容量:W=5

表格结构:

i (物品数) \ j (容量)012345
0 (无物品)000000
1 (物品A)??????
2 (物品A,B)??????
3 (物品A,B,C)??????

填表逻辑(核心)

我们每次填一个格子 dp[i][j],都要做个决定:拿不拿第 i 个宝贝?

  1. 如果你不拿第 i 个宝贝
    那你的最大价值,就和只考虑前 i-1 个宝贝时,容量为 j 的最大价值一样。
    也就是 dp[i-1][j]

  2. 如果你拿第 i 个宝贝
    前提是你的背包容量 j 足够大(j >= 第 i 个宝贝的重量)。
    如果你拿了,你的背包还剩下 j - 第 i 个宝贝的重量 的容量。
    剩下的容量能装多少价值?答案在表格的上一行,也就是 dp[i-1][j - 第 i 个宝贝的重量]
    所以,总价值是 dp[i-1][j - 第 i 个宝贝的重量] + 第 i 个宝贝的价值

我们取这两种情况中价值最大的一个,作为 dp[i][j] 的值。


4. 实际推演

宝贝A (重1, 值6)
  • 填第1行
  • dp[1][0]:容量0,装不下A,价值为0。
  • dp[1][1]:容量1,可以装下A。拿了A,价值是6。
  • dp[1][2]:容量2,可以装下A,价值是6。
  • **总结:**只要容量大于等于1,就能装下宝贝A,价值都是6。
  • dp 第1行:[0, 6, 6, 6, 6, 6]
宝贝B (重2, 值10)
  • 填第2行
  • dp[2][0]:容量0,装不下B,沿用上一行(不拿B)的值,dp[1][0]=0。
  • dp[2][1]:容量1,装不下B,沿用上一行,dp[1][1]=6。
  • dp[2][2]:容量2,可以装下B。
    • 不拿B:价值是 dp[1][2]=6
    • 拿B:价值是 dp[1][2-2]+10 = dp[1][0]+10 = 0+10 = 10
    • max(6, 10) = 10
  • dp[2][3]:容量3,可以装下B。
    • 不拿B:价值是 dp[1][3]=6
    • 拿B:价值是 dp[1][3-2]+10 = dp[1][1]+10 = 6+10 = 16
    • max(6, 16) = 16
  • dp[2][4]:容量4,可以装下B。
    • 不拿B:价值是 dp[1][4]=6
    • 拿B:价值是 dp[1][4-2]+10 = dp[1][2]+10 = 6+10 = 16
    • max(6, 16) = 16
  • dp[2][5]:容量5,可以装下B。
    • 不拿B:价值是 dp[1][5]=6
    • 拿B:价值是 dp[1][5-2]+10 = dp[1][3]+10 = 6+10 = 16
    • max(6, 16) = 16
  • dp 第2行:[0, 6, 10, 16, 16, 16]
宝贝C (重3, 值12)
  • 填第3行
  • dp[3][0]:容量0,装不下C,沿用 dp[2][0]=0。
  • dp[3][1]:容量1,装不下C,沿用 dp[2][1]=6。
  • dp[3][2]:容量2,装不下C,沿用 dp[2][2]=10。
  • dp[3][3]:容量3,可以装下C。
    • 不拿C:价值是 dp[2][3]=16
    • 拿C:价值是 dp[2][3-3]+12 = dp[2][0]+12 = 0+12 = 12
    • max(16, 12) = 16
  • dp[3][4]:容量4,可以装下C。
    • 不拿C:价值是 dp[2][4]=16
    • 拿C:价值是 dp[2][4-3]+12 = dp[2][1]+12 = 6+12 = 18
    • max(16, 18) = 18
  • dp[3][5]:容量5,可以装下C。
    • 不拿C:价值是 dp[2][5]=16
    • 拿C:价值是 dp[2][5-3]+12 = dp[2][2]+12 = 10+12 = 22
    • max(16, 22) = 22

最终,我们填完了所有格子。表格的右下角 dp[3][5] 的值是 22,这就是最终的答案。

总结

  • 定义:动态规划是把一个大问题拆解成互相联系的小问题,然后通过解决这些小问题,来逐步得到大问题的答案。
  • 逻辑:我们用 dp[i][j] 这样的表格来存储每个小问题的答案。
  • 转移方程:我们用 dp[i-1][...] 的答案,来计算 dp[i][...] 的答案。这就是“状态转移方程”,它连接了不同的“小问题”。

现在你觉得理解起来有没有更容易一些?


文章转载自:

http://2GrSPa5b.frbhq.cn
http://gRePo5Zd.frbhq.cn
http://qhRJzRIO.frbhq.cn
http://XnJyXNF7.frbhq.cn
http://7rW4xtCO.frbhq.cn
http://cdUwQZ2d.frbhq.cn
http://fJhOYGco.frbhq.cn
http://pATN3PBh.frbhq.cn
http://sOmTXT1W.frbhq.cn
http://0r6BDTfP.frbhq.cn
http://r3YWVKXW.frbhq.cn
http://A9mjdLsZ.frbhq.cn
http://SBn0WhHp.frbhq.cn
http://MWfoWyrf.frbhq.cn
http://OJ5CC7rc.frbhq.cn
http://JuKg0Eqd.frbhq.cn
http://HG18XKZP.frbhq.cn
http://sNzPz65J.frbhq.cn
http://Q6vNvSD9.frbhq.cn
http://5HoqSadK.frbhq.cn
http://dDImD9wa.frbhq.cn
http://hM8Kp3az.frbhq.cn
http://7gVOHRc6.frbhq.cn
http://zTYPgxpj.frbhq.cn
http://SE7ivnEP.frbhq.cn
http://e8OdtSTK.frbhq.cn
http://kdJclhSL.frbhq.cn
http://9P98eKSA.frbhq.cn
http://COz3y0T6.frbhq.cn
http://i6z19AGa.frbhq.cn
http://www.dtcms.com/a/365765.html

相关文章:

  • 新闻发稿平台哪家好?新闻源发表新闻媒体收录平台测评
  • Redis基础篇
  • 模仿学习模型diffusion_policy部署
  • 宋红康 JVM 笔记 Day12|执行引擎
  • MySQL索引分类
  • 网络通信与协议栈 -- OSI,TCP/IP模型,协议族,UDP编程
  • GitLab Boards 深度解析:选型、竞品、成本与资源消耗
  • Python学习笔记--使用Django查询数据
  • 基于 HTML、CSS 和 JavaScript 的智能图像虚化系统
  • 年成本下降超80%,银行数据治理与自动化应用实录
  • 什么是Agent?小白如何学习使用Agent?一篇文档带你详细了解神秘的Agent
  • 正运动控制卡学习-网络连接
  • Git配置:禁用全局HTTPS验证
  • 【Unity UGUI介绍(0)】
  • 计算机组成原理(1:计算机系统组成)
  • 系统编程day2-系统调用
  • day4
  • 「数据获取」《吉林企业统计年鉴(2004)》(获取方式看绑定的资源)
  • 基于jmeter+perfmon的稳定性测试记录
  • logging:报告状态、错误和信息消息
  • Linux的墙上时钟和单调时钟的区别
  • 检查系统需求
  • 如何解决pip安装报错ModuleNotFoundError: No module named ‘isort’问题
  • Linux编程——网络编程(tcp)
  • 演员-评论员算法有何优点?
  • JavaScript原型与原型链:对象的家族传承系统
  • 3-7〔OSCP ◈ 研记〕❘ WEB应用攻击▸REST API概述
  • 漫谈《数字图像处理》之图像清晰化处理
  • 更新远程分支 git fetch
  • 计算机三级网络应用题大题技巧及练习题