思路展示

问题转化为:把一堆石头分成两堆,求两堆石头重量差最小值
进一步分析:要让差值小,两堆石头的重量都要接近sum/2;我们假设两堆分别为A,B,A<sum/2,B>sum/2,若A更接近sum/2,B也相应更接近sum/2
进一步转化:将一堆stone放进最大容量为sum/2的背包,求放进去的石头的最大重量MaxWeight,最终答案即为sum-2*MaxWeight;

示例代码

class Solution {
public:
    int lastStoneWeightII(vector<int>& stones) {
        int len=stones.size();
        int sum=0;
        for(int stones:stones){
            sum+=stones;
        }

        int target=sum/2;
        //dp[j]表示容量(这里说容量更形象,其实就是重量)为j的背包,最多可以背最大重量为dp[j]。
        vector<int> dp(target+1);
        //初始化第一列的所有值都为true
        for(int i=1;i<=len;i++){
            for(int j=target;j>=stones[i-1];j--){
                //dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);
                dp[j]=max(dp[j],dp[j-stones[i-1]]+stones[i-1]);
            }
        }
        //在计算target的时候,target = sum / 2 因为是向下取整,所以sum - dp[target] 一定是大于等于dp[target]的。
        return (sum-dp[target])-dp[target];
    }
};

效果展示

LeetCode---1049. 最后一块石头的重量 II(动态规划)_动态规划

相似题目

416. 分割等和子集