一:题目
二:上码
class Solution {
public:
/**
思路:1.分析题意
只要我们将石头分为尽可能相同的两堆,他们的重量相减后剩余的重量就是最小。
物品的重量为stones[i];物品的价值也为stone[i];
temp代表总重量的一半
那么我们最终得到的stones[temp]:就是背包容量为temp的最大重量为 dp[temp] 而temp也是代表
所有石头的总重量的一半(但是是小于一半的 因为我们是 sum/2 向下取正的)
2.动态规划五步走
1>:确定dp数组 以及下标的含义
dp[j] 表示容量(其实就是重量)为j的背包所能装下的最大重量
2>:确定dp数组的状态递推公式
dp[j] = max(dp[j],dp[j-stones[i]] + stones[i])
3>:确定dp数组的初始化
初始化为0 因为 我们要求max
4>:确定dp数组的遍历顺序
外层是石头,内层是重量(逆序)
5>:举例验证
2 7 4 1 8 1 temp = sum/2 = 11
0 1 2 3 4 5 6 7 8 9 10 11
stones[0] 0 0 2 2 2 2 2 2 2 2 2 2
stones[1] 0 0 2 2 2 2 2 7 7 9 9 9
stones[2] 0 0 2 2 2 2 2 7 7 9 9 11
stones[3] 7 9 10 11
stones[4] 11
stones[5] 11
dp[temp] = 11;//一半的石头
sum - dp[temp] = 12//另一半的石头
12 - 11 = 1;
*/
int lastStoneWeightII(vector<int>& stones) {
vector<int> dp(1501,0);
int sum = accumulate(stones.begin(),stones.end(),0);
int temp = sum/2;
for(int i = 0; i < stones.size(); i++) {
for(int j = temp; j >= stones[i]; j--) {
dp[j] = max(dp[j],dp[j-stones[i]] + stones[i]);
}
}
return (sum-dp[temp]) - dp[temp];//这个是代表的是 一半的重量 减去 另一半的重量
}
};