题目链接https://leetcode-cn.com/problems/last-stone-weight-ii/
本题其实就是尽量让石头分成重量相同的两堆
,相撞之后剩下的石头最小,这样就化解成01背包问题了。
接下来进行动规五步曲:
确定dp数组以及下标的含义
dp[j]表示容量为j的背包,最多可以背dp[j]这么重的石头。
确定递推公式
dp[j] = max(dp[j], dp[j - stones[i]] + stones[i]);
dp[j - stones[i]] + stones[i]中 又有- stones[i] 又有+stones[i],看着有点晕乎。
还是要牢记dp[j]的含义,要知道
dp[j - stones[i]]
为 容量为j - stones[i]
的背包最大所背重量。
dp数组如何初始化
既然 dp[j]中的j表示容量,那么最大容量(重量)是多少呢,就是所有石头的重量和。
而我们要求的target其实只是最大重量的一半,所以可以把石头遍历一遍,计算出石头总重量 然后除2,得到dp数组的大小。
接下来就是如何初始化dp[j]呢,因为重量都不会是负数,所以dp[j]都初始化为0就可以了,这样在递归公式dp[j] = max(dp[j], dp[j - stones[i]] + stones[i]);中dp[j]才不会被初始值所覆盖。
代码为:vector<int> dp(target+1,0);
确定遍历顺序
如果使用一维dp数组,物品遍历的for循环放在外层,遍历背包的for循环放在内层,且内层for循环倒叙遍历!
for