LeetCode 每日一题 2021-5-8 ( 最后一块石头的重量 II)

1049. 最后一块石头的重量 II

难度中等290

有一堆石头,用整数数组 stones 表示。其中 stones[i] 表示第 i 块石头的重量。

每一回合,从中选出任意两块石头,然后将它们一起粉碎。假设石头的重量分别为 x 和 y,且 x <= y。那么粉碎的可能结果如下:

  • 如果 x == y,那么两块石头都会被完全粉碎;
  • 如果 x != y,那么重量为 x 的石头将会完全粉碎,而重量为 y 的石头新重量为 y-x

最后,最多只会剩下一块 石头。返回此石头 最小的可能重量 。如果没有石头剩下,就返回 0

 

思路: 若石头可以对应粉碎,则可以将石头分为两部分 。

            其中 X,Y表示各部分的重量,M为石头的总重量,则 X+Y = M;    

            min(X,Y)<= M/2、max(X,Y) >= M/2 ;

            实际粉碎的重量为 2*min(X,Y);

            则最终剩余的部分为 ans = M - 2*min(X,Y) =   |X-Y| >= 0 ; 

            获取最小的 ans ,为 X 和 Y 的差值最小,即 min(X,Y)尽量大,或者 max(X,Y)尽量小。

①将最小剩余重量寻找问题,转换为 小于 M/2 的最大可能重量,或者大于 M/2 的最小可能重量。

②不大于某值的最大可能重量(背包问题-DP)

 

代码:

int lastStoneWeightII(vector<int>& stones) {
    int sum=0;
    for(auto index:stones) sum+=index;
    int len=sum/2;
    bool data[len+1];
    memset(data,false,sizeof(data));
    data[0]=true;
    for(int index:stones){
        for(int j=len;j>=index;--j){
            data[j] = data[j] || data[j-index];
        }
    }
    for(int i=len;;--i){
        if(data[i]) return sum - 2*i;
    }
    return sum;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值