力扣1049.最后一块石头的重量(01背包)之理解篇

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

cpp 复制代码
class Solution {
public:
    int lastStoneWeightII(vector<int>& stones) {
        int sumNum = 0;
        for(int i = 0;i < stones.size();++i){
            sumNum += stones[i];
        }
        int target = sumNum / 2;
        vector<int>dp(target + 1, 0);
        for(int i = 0;i < stones.size();++i){
            for(int j = target;j >= stones[i];--j){
                dp[j] = max(dp[j], dp[j - stones[i]] + stones[i]);
            }
        }
        return sumNum - dp[target] - dp[target];
    }
};

思考了很久不知道为什么将一堆石头划分为质量最接近的两堆,然后他们之差就是最后的结果.

后来仔细想了想还是想出来了,以下是我的理解:

可以将两堆抽象为两杯水,我们把两堆石头各化为水装进两个杯子,如果两个杯子水的总量相同,证明我们可以将所有石头全部碰碎(目前为止没有问题)

我们采取的方法是将石头划为质量最接近的两堆,因为质量最接近,如果质量相等直接返回0.如果不相等,说明我们使用的01背包方法已经为我们找到了尽可能装满sumNum/2的最优解,即能够使得碰撞后剩下的最后一个石头最小,(我的疑虑是为什么结果不是一边剩下两块石头或更多,但实际上,这种情况并不会出现,因为如果出现这种情况,说明左右总大小还不是最接近sumNum/2的最优解),最优解就是保证了左右碰撞后只能剩下最后一个石头,并且其在所有碰撞结果中最小.

这题我简化为两杯水去理解,结果就是豁然开朗,可以吧石头的碰撞简单地想象为消消乐(水与水之间的消消乐).

题外话:二刷到动态规划,还是觉得自己在动态规划这方面没有充分的理解,我觉得未来还要考虑三刷

相关推荐
XYY36914 分钟前
前缀和 一维差分和二维差分 差分&差分矩阵
数据结构·c++·算法·前缀和·差分
longlong int24 分钟前
【每日算法】Day 16-1:跳表(Skip List)——Redis有序集合的核心实现原理(C++手写实现)
数据库·c++·redis·算法·缓存
24白菜头24 分钟前
C和C++(list)的链表初步
c语言·数据结构·c++·笔记·算法·链表
刺客-Andy1 小时前
前端加密方式 AES对称加密 RSA非对称加密 以及 MD5哈希算法详解
前端·javascript·算法·哈希算法
记得早睡~1 小时前
leetcode122-买卖股票的最佳时机II
javascript·数据结构·算法·leetcode
黄油烤菠萝1 小时前
蓝桥杯-卡java排序
c++·算法·蓝桥杯
不要天天开心1 小时前
Scala集合
图像处理·算法·机器学习·scala
uhakadotcom2 小时前
Google Cloud Dataproc:简化大数据处理的强大工具
后端·算法·面试
uhakadotcom2 小时前
PyTorch 分布式训练入门指南
算法·面试·github
uhakadotcom2 小时前
PyTorch 与 Amazon SageMaker 配合使用:基础知识与实践
算法·面试·github