- 思路
首先,前面的结果对后面的结果有相关性,有重叠子问题,考虑动态规划。
参考题解
初始化就是全为0。
举例
- 其实最难想的就是本题其实就是尽量让石头分成重量相同的两堆,相撞之后剩下的石头最小,这样就化解成01背包问题了。这里这句话,怎么考虑成为背包问题,然后就是背包容量是什么,物品价值是什么,计算得到的是什么,要返回什么?
背包问题有三个要素:背包的容量(sum(stones)/2),物品的重量(stones[i]),物品的价值(stones[i],最后我们想要的是背包尽可能装得多,而这个多不多的体现就是在指定的容量下装尽量重的石头,所以价值对应石头重量)。
class Solution {
public int lastStoneWeightII(int[] stones) {
int totalStone = 0;
for (int i = 0; i < stones.length; i++) {
totalStone += stones[i];
}
int bagWeight = totalStone / 2;
int[] dp = new int[bagWeight + 1];
for (int i = 0; i < stones.length; i++) {
for (int j = bagWeight; j >= stones[i]; j--) {
dp[j] = Math.max(dp[j], dp[j - stones[i]] + stones[i]);
}
}
// totalStone - dp[bagWeight]等于stones的一半
// 但是bagWeight是向下取整的,所以大于等于一半
// dp[bagWeight]表示总重量的一半的背包容量能够容下的实际最大石头重量
// 然后两者做差得到相撞之后剩下的石头最小值
return totalStone - dp[bagWeight] - dp[bagWeight];
}
}