01背包问题简易讲解
发布日期:2021-06-29 12:22:13
浏览次数:3
分类:技术文章
本文共 1990 字,大约阅读时间需要 6 分钟。
序:
01背包问题是一类经典的动态规划问题,每一个物品可以选或者不选。通过动态规划,可以使得前i件物品的选择仅与前i-1件的物品选择有关,是不是有点像马尔可夫链?题目概述:
有n件物品,每件物品的重量为w[i],价值为c[i]。现有一个容量为V的背包,问如何将物品放入背包,使得背包内物品的总价值最大。其中每件物品只有1件。分析:
如果每件物品均判断在或不在,则会导致2^n的复杂度,这是令人崩溃的。因此我们另寻僻径。令dp[i][v]表示前i件物品(1 <= i <= n, 0 <= v <= V)装入容量为v的背包中所能获得的最大价值,怎么求解dp[i][v]呢?有两种策略。
1:不放第i件物品,此时dp[i][v] = dp[i-1][v] 2:放第i件物品,此时dp[i][v] = dp[i-1][v-w[i]] + c[i],即通过牺牲空间换取价值。因此,状态转移方程即为:
dp[i][v] = max(dp[i-1][v],dp[i-1][v-w[i]]+c[i]) 其中(1 <= i <= n, w[i] <= v <= V) 边界为:dp[0][v] = 0 (0 <= v <= V) 最后,对dp[n][v] (0 <= v <= V),也就说选到最后一个物品时,剩下的容量为v。由于剩下的容量由前n-1个物品的选择决定,所以需要对所有的dp[n][v]取最大值后方为结果。举一个例子方便说明:
5 8 // n == 5, V == 83 5 1 2 2 // w[i]4 5 2 1 3 // c[i]
核心代码如下:
for(int i = 1; i <= n; i++){ for(int v = w[i]; v <= V; v++) { dp[i][v] = max(dp[i-1][v],dp[i-1][v-w[i]]+c[i]); }}
我们来模拟一下:
i=1时:
v从3到8到中间取值, w[1] = 3, c[1] = 4 dp[1][3] = max(0, 3) = 4;同理,dp[1][k] = 4 (k从3到8中取值)i=2时:
v从5到8中间取值,w[2] = 5, c[2] = 5 dp[2][5] = max(4,5) = 5 dp[2][6] = max(4,5) = 5 = dp[2][7] dp[2][8] = max(4, dp[1][3] + 5) = 9i=3时:
v从1到8中间取值,w[3] = 1, c[3] = 2 dp[3][1] = … = dp[3][4] = 2 dp[3][5] = 5 dp[3][6] = max(dp[2][6], dp[2][5] + 2) = 7 dp[3][7] = max(dp[2][7], dp[2][6] + 2) = 7 = dp[3][8]i=4时:
v从2到8中间取值,w[4] = 2, c[4] = 1 dp[4][2] = max(dp[3][2], dp[3][0] + 1) = 2 dp[4][3] = max(dp[3][3], dp[3][1] + 1) = 3 dp[4][4] = max(dp[3][4], dp[3][2] + 1) = 3 dp[4][5] = max(dp[3][5], dp[3][3] + 1) = 5 dp[4][6] = max(dp[3][6], dp[3][4] + 1) = 7 dp[4][7] = max(dp[3][7], dp[3][5] + 1) = 7 dp[4][8] = max(dp[3][8], dp[3][6] + 1) = 8i=5时:
v从2到8中间取值,w[4] = 2, c[4] = 3 dp[5][2] = max(dp[4][2], dp[4][0] + 3) = 3 dp[5][3] = max(dp[4][3], dp[4][1] + 3) = 3 dp[5][4] = max(dp[4][4], dp[4][2] + 3) = 5 dp[5][5] = max(dp[4][5], dp[4][3] + 3) = 6 dp[5][6] = max(dp[4][6], dp[4][4] + 3) = 7 dp[5][7] = max(dp[4][7], dp[4][5] + 3) = 8 dp[5][8] = max(dp[4][8], dp[4][6] + 3) = 10因此,按照这两重循环走一遍,最终答案为10。
总结:
书上是对最后一个循环取最大值,但我根据观察发现当容量最大时dp才是最大的。那么最大容量能不能直接输出dp[n][V]呢?欢迎大家一起探讨!转载地址:https://bridge-killer.blog.csdn.net/article/details/115261267 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
网站不错 人气很旺了 加油
[***.192.178.218]2024年04月10日 20时37分39秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
了解这些操作,Python中99%的文件操作都将变得游刃有余!
2019-04-29
知道如何操作还不够!深入了解4大热门机器学习算法
2019-04-29
只有经历过,才能深刻理解的9个编程道理
2019-04-29
发现超能力:这些数据科学技能助你更高效专业
2019-04-29
AI当道,人工智能将如何改变金融业?
2019-04-29
消除性别成见,技术领域需要更多“乘风破浪的姐姐”
2019-04-29
7行代码击败整个金融业,这对20多岁的爱尔兰兄弟是如何做到的?
2019-04-29
2020十大编程博客:私藏的宝藏编程语言博客大放送!
2019-04-29
编程中的角色选择:哪类工作角色最适合你?
2019-04-29
10种算法一文打尽!基本图表算法的视觉化阐释
2019-04-29
未来属于人工智能工程师,但成功转型不容易
2019-04-29
科技界“挠头”:困扰科技界可持续发展的难题
2019-04-29
20年后,这5种编码语言可能就消失了……
2019-04-29
标准出现问题,人工智能正在走向错误的方向
2019-04-29
如何使用Python实现最低有效位隐写术?
2019-04-29
湮没在赞誉之中,科学史上鲜为人知的五大“败笔”
2019-04-29
别再对分类变量进行独热编码!你还有更好的选择
2019-04-29
如果不能用Python执行机器学习,那该用什么呢?
2019-04-29
不论何时,互联网从业者一直幸福着~
2019-04-29
mysql用户口令中含有特殊字符@的情况下,如何正确链接数据库
2019-04-29