LC1409.最后一块石头的重量 II (动态规划(01背包)-中等)

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

题目:有一堆石头,用整数数组 stones 表示。其中 stones[i] 表示第 i 块石头的重量。每一回合,从中选出任意两块石头,然后将它们一起粉碎。假设石头的重量分别为 x 和 y,且 x <= y。那么粉碎的可能结果如下:

如果 x == y,那么两块石头都会被完全粉碎;
如果 x != y,那么重量为 x 的石头将会完全粉碎,而重量为 y 的石头新重量为 y-x。
最后,最多只会剩下一块 石头。返回此石头 最小的可能重量 。如果没有石头剩下,就返回 0

分析:根据LC494的思想,做如下分析

        ① 由题目可知: pos + neg = sum  求 pos - neg 最小 即  sum-2neg 最小   sum-2neg>=0  neg<=sum/2 当取 = 时,有最小值。(即neg要在不超过sum/2的情况下尽可能的大)
        ② 转化为背包问题:
        物品容量:stones(n=len(stones))  背包容量:bag=sum/2   价值:stones
        状态:d[i][j] 当 背包容量为 j 时,第0-i个物品的最大价值
        状态转移方程:d[i][j] = max(不放当前物品的价值,当前物品价值+背包剩余空间产生的价值)
                           = max(d[i-1][j], stones[i-1]+d[i-1][j-stones[i-1]])
        初始状态:   背包[0-bag]   物品[0-n]
                d[0][:]=0 当物品为空时候  无论背包多大  价值为0
                d[:][0]=0 当背包容量为0时候,什么都放不下,价值为0

PS:①当感觉像0-1背包问题,就要对应各个已知往上边靠。

        ②注意最后返回的是 sum(stones) - d[-1][-1]*2

代码:

def lastStoneWeightII2(stones):
    n, bag = len(stones), sum(stones)//2
    d = [[0 for _ in range(bag+1)] for _ in range(n+1)]

    for i in range(1, n+1):
        for j in range(1, bag+1):
            if j >= stones[i-1]:
                d[i][j] = max(d[i-1][j], stones[i-1] + d[i-1][j-stones[i-1]])
            else:
                d[i][j] = d[i-1][j]
    return sum(stones) - d[-1][-1]*2

路虽远,行则将至。事虽难,做则必成 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值