Tokic
Tokic
唯一需要注意的是 j 应该从后往前反向遍历,因为每个物品(或者说数字)只能用一次,以免之前的结果影响其他的结果。 --------------------- 这句话没读懂啊,为啥会影响之前的其他结果? 为啥原来二维数组不用反向遍历?二维数组不能反过来遍历吧,前一个值都没有算出来,反过来不就不能利用上一个计算出来的值了吗?
还是没理解。尝试按之前的遍历方向那篇博文 https://labuladong.gitee.io/algo/3/24/71/ 画了矩阵图,dp[i][j] 来自于 dp[i-1][j]和 dp[i-1][j-nums[i]] ,那篇博文dp[i][j]来自dp[i-1][j] 和dp[i-1][j-1]、dp[i][j-1],博文说要正向遍历 因为,这样每一步迭代的左边、上边、左上边的位置都是 base case 或者之前计算过的,而且最终结束在我们想要的答案 dp[m][n]。 我画了图,这道题的情况base case 和它相同,方向也一致,为什么这个就是从右到左了,画图的时候怎么区别这种情况呢?
@zhongweiLeex 我判断方向错了吗?我画出来两个方向都是左上到右下。区别在于倾斜度不同,为什么一个需要反方向遍历,一个不用呢? 
这道题和之前之后的的文章有点不一样,之前都是dp[]或dp[][],为什么这里要用一个函数呢?为什么不用二维dp数组呢?什么时候该用函数呢?
@NiceMartin 如果把 第 i 物品装入背包的情况下, dp[i][j] 不是应该等于dp[i-1][j-coins[i-1]] 吗? 我也这么觉得。如果你决定使用这个面值的硬币,那么就应该关注如何凑出金额 j - coins[i-1]。 比如说,你想用面值为 2 的硬币凑出金额 5,那么如果你知道了凑出金额 3 的方法,再加上一枚面额为 2 的硬币,不就可以凑出 5 了嘛。 所以先dp[i-1][j-coins[i-1]] ,再加上这个面值的硬币。组合数不变。 不过从二维优化到一维之后是一样的。
但是把dp[i][j - coins[i-1]]改成 dp[i-1][j-coins[i-1]] ,提交是错的!
感谢大佬的答复,我终于明白了。我理解的是这样的: dp[i][j]中使用 i 的次数是 [0, +∞],当不使用 i 的时候,dp[i][j]=dp[i-1][j]; 所以也是只有在不使用 i 这个硬币的时候,才会 dp[i][j-coins[i-1]] = dp[i-1][j-coins[i-1]]。假设等号左边是(A),等号右边是(B),那么 B 就是 A 的子集!A 还包括了一部分 C。 —————— 比如说,你想用面值为 2 的硬币凑出金额 5,那么如果你知道了凑出金额 3 的方法,再加上一枚面额为 2 的硬币,不就可以凑出 5...