leetcode1049-最后一块石头的重量

/**
 * @param {number[]} stones
 * @return {number}
 */
var lastStoneWeightII = function(stones) {
    // dp 数组最大容量是 max(stones[length]) * max(stones[i]) /2 + 1
    // dp[j]的含义是 容量为j的背包 最多可以背dp[j]这么多的石头 
    let dp =  new Array(15001).fill(0);    
    let sum = 0;
    for(let i = 0;i<stones.length;i++){
        sum += stones[i];
    }
    // target 需要向下取整 js里的parseInt去掉小数点可以满足
    let target =parseInt(sum/2);
    // 遍历 先正序物品 再倒序背包
    for(let i = 0;i<stones.length;i++){
        for(let j = target;j>=stones[i];j--){
            dp[j] =Math.max(dp[j],dp[j - stones[i]] + stones[i])
            
        }
    }
    return sum - dp[target] - dp[target];

};

把石头分成质量接近于 sum/2 的两堆,注意sum/2 是整数,这里我是向下取整的,因为求的是被减石头堆的重量,也就是小的那堆。

dp数组含义:容量为 j 的背包能装的石头重量为dp[j] ,所以按照题意,dp的长度为石头重量的一半。初始化,因为石头重量肯定是大于零的,为了之后初始化值都可以被覆盖,所以初始化为零。

然后就是传统的01背包遍历了,先遍历物品,再遍历背包(倒序遍历),取最大值

链接:参考地址(我觉得写得很好很清楚)

最后一块石头的重量:从一堆石头中,每次拿两块重量分别为x,y的石头,若x=y,则两块石头均粉碎;若x<y,两块石头变为一块重量为y-x的石头求最后剩下石头的最小重量(若没有剩下返回0)
问题转化为:把一堆石头分成两堆,求两堆石头重量差最小值
进一步分析:要让差值小,两堆石头的重量都要接近sum/2;我们假设两堆分别为A,B,A<sum/2,B>sum/2,若A更接近sum/2,B也相应更接近sum/2
进一步转化:将一堆stone放进最大容量为sum/2的背包,求放进去的石头的最大重量MaxWeight,最终答案即为sum-2*MaxWeight

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值