chapter_dynamic_programming/knapsack_problem/ #581
Replies: 47 comments 62 replies
-
感觉方法1和方法2是根据状态转移方程硬写的,只是动态规划的递归写法.最小路径的方法1和方法2也是这样的,
|
Beta Was this translation helpful? Give feedback.
-
能否考虑”from functools import cache“实现记忆化搜索,我感觉这样记忆化搜索理解起来更简单 |
Beta Was this translation helpful? Give feedback.
-
老师您好,我想请教一下,假如背包还有一个类似重量的元素,但是要求这个元素的总和必须大于某个值该怎么处理 |
Beta Was this translation helpful? Give feedback.
-
图14-19内,因为找到记录被剪掉的 |
Beta Was this translation helpful? Give feedback.
-
老师,这个我其实不是很理解这个思路。 因为动态规划按照之前的描述应该是从低到顶的计算过程。 所以 dp[i][j] 的描述中是不是要换一种思路好一些:i 表明当前编号物品的选择,j 表明当前容量的大小 也就是说是从 0 -> cap 的遍历过程,如果 j 理解为剩余容量,不是很理解,求老师解惑 |
Beta Was this translation helpful? Give feedback.
-
图14-20的<12>两个箭头颜色是不是反了? |
Beta Was this translation helpful? Give feedback.
-
总结: 定义 dp[n][m] 为背包容量为m时,考虑前n个物品的放入取舍后对应的最大总价值。 由于每个物品要么放入,要么不放入,只有两种可能,那么找出状态转移方程的思路就很自然了: (A) 在决定完前m-1个物品是否放入后,第m个物品放进了背包里。 对于第一种情况,显然总价值就等于在决定完前m-1个物品是否放入后的最大价值直接加上第m个物品的价值val(m-1)。并且由于放进了物品m,可知在放入第m个物品前的状态对应的容量为n-wgt[m-1],即: 对于第二种情况,物品m没有放进去,那么总价值不变,容量不变,即 于是最大总价值就是在两种结果中取较大值dp[m][n]=max(Val_A,Val_B)。于是状态转移方程为: 需要特别注意的是: (1) 由于要保证物品m能放进去,还得保证n-wgt[m-1]>=0,否则物品m并不能被放进,从而可以直接得出dp[m][n]=dp[m-1][n]=val_2。 (2) 显然背包的容量越大,我们能获得的最大价值也就越高。这也就是为什么在Val_A中,对于dp[m-1]这个状态赋予的容量是n-wgt[m-1],而不是其他更小的容量。当然,赋予比n-wgt[m-1]更大的容量可能会得到更大值,但就没法把物品m再放进去了。同理,在Val_B中,由于没有放物品m进去,我们赋予状态dp[m-1]的最大容量就是n,这样才能获得最大价值dp[m][n]。 |
Beta Was this translation helpful? Give feedback.
-
「剩余容量」这个表述理解了好久,不知道是放完 i 物品后剩余,还是轮到 i 物品的时候背包剩余的量,直接转换为背包容量感觉好理解很多 |
Beta Was this translation helpful? Give feedback.
-
对于倒序遍历,我是这样理解的:每一次循环本质是利用积累的数据计算当前状态并保存当前状态作为下一行计算的依据,倒序遍历在完成状态计算后更新当前状态并不影响后续遍历的计算,因为后续遍历的cap小所以用不到当前数据,对于优化后的数组来说,相当于在首部保存上一行的价值,在尾部保存当前行的价值。 另外,如果容量是浮点数,是不是需要计算出任意一个或多个wgt相加的组合结果,其元素的有序列表作为cap的遍历范围? |
Beta Was this translation helpful? Give feedback.
-
提个建议:不同配图中的 物品 价值、重量 统一下,初学者更好理解 |
Beta Was this translation helpful? Give feedback.
-
在i等于1时,随着c的增加,为什么最大df还是等于5,不是应该变成11 ,16吗,求解答 |
Beta Was this translation helpful? Give feedback.
-
k神,我有一个问题,就是在二维数组的动态规划过程中,两个for循环的先后顺序更改后并不影响结果,但为什么空间优化后的动态规划,改变两个for循环的先后顺序,结果就不对了呢 |
Beta Was this translation helpful? Give feedback.
-
请问背包问题中物品的重量一般都是像10,20,30(背包容量对应10的整数倍)或者1,2,3,(背包容量对应1的整数倍),并且是有序的吗? |
Beta Was this translation helpful? Give feedback.
-
|
Beta Was this translation helpful? Give feedback.
-
使用动态规划得到最大值后,我想知道最好的解决方案(选择那些物品)是什么,求一个反向推导出最佳方案的办法 |
Beta Was this translation helpful? Give feedback.
-
花了很久才看明白dp表(说明有点短),推荐这个视频:https://www.bilibili.com/video/BV1pY4y1J7na/ |
Beta Was this translation helpful? Give feedback.
-
个人觉得这段话中的“剩余背包容量c”很容易造成歧义,以为是放置了物品i(或前i个物品)后,背包还剩下容量c,但实际这里指的是用容量c去装前i个物品。比如下文不远处的dp[n, cap],当时在读的时候就理解成“前n个物品在剩余容量cap中的最大价值”,感觉有点别扭,那背包总容量岂不是“cap+sum(前n个物品的重量)”?dp[i,c]的解释改为“用容量c去装前i个物品的最大价值”则没有歧义。 |
Beta Was this translation helpful? Give feedback.
-
for (int c = cap; c >= wgt[i-1]; c--) |
Beta Was this translation helpful? Give feedback.
-
注意,文中说的前i-1和代码中[i-1]是不同的意思: 如有表述错误请指正。 |
Beta Was this translation helpful? Give feedback.
-
在python下暴力搜索反而是时间最短的,是因为数据量不够大么? |
Beta Was this translation helpful? Give feedback.
-
为什么空间优化的时候采用正向遍历会出现覆盖问题,而倒序遍历不会 |
Beta Was this translation helpful? Give feedback.
-
有没有覆盖问题是取决于最小子问题的结构的。以矩阵的格子作为不同状态: 假如 s[i][j] 跟 s[i - 1][j] 和 s[i - 1][j - 1] 有关,即当前格子的左侧和左上,则压缩空间时正序遍历无法获取左上的格子历史信息。 同理,s[i][j] 跟 s[i - 1][j] 和 s[i][j - 1] 和 s[i - 1][j - 1]有关,即左侧,正上,左上,压缩空间时正序遍历也会丢失左上格子历史信息。
|
Beta Was this translation helpful? Give feedback.
-
// 状态转移 |
Beta Was this translation helpful? Give feedback.
-
dp[i][c] = max(dp[i - 1][c], dp[i - 1][c - wgt[i - 1]] + val[i - 1]); |
Beta Was this translation helpful? Give feedback.
-
画的真是太好了👍 |
Beta Was this translation helpful? Give feedback.
-
为了便于理解, 建议作者将物品编号也从0 开始。 另外物品编号从1开始设计, 反而让代码变得不好读 |
Beta Was this translation helpful? Give feedback.
-
空间优化这段里, |
Beta Was this translation helpful? Give feedback.
-
for (let c = cap; c > 0; c--) {
if (wgt[i - 1] <= c) dp[c] = Math.max(dp[c], dp[c - wgt[i - 1]] + val[i - 1])
} 简写成以下形式,应该不会影响结果吧。 for (let c = cap; c >= wgt[i - 1]; c--) {
dp[c] = Math.max(dp[c], dp[c - wgt[i - 1]] + val[i - 1])
} |
Beta Was this translation helpful? Give feedback.
-
“如果采取正序遍历,那么遍历到 时,左上方 值可能已经被覆盖,此时就无法得到正确的状态转移结果。“ |
Beta Was this translation helpful? Give feedback.
-
上面有地方写错了 |
Beta Was this translation helpful? Give feedback.
-
chapter_dynamic_programming/knapsack_problem/
动画图解、一键运行的数据结构与算法教程
https://www.hello-algo.com/chapter_dynamic_programming/knapsack_problem/
Beta Was this translation helpful? Give feedback.
All reactions