力扣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的最优解),最优解就是保证了左右碰撞后只能剩下最后一个石头,并且其在所有碰撞结果中最小.

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

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

相关推荐
mCell3 小时前
Lua 编程入门:从基础语法到元表
javascript·算法·lua
wuyk5555 小时前
98.C语言易混难点:字符数组与字符串指针的底层差异
c语言·开发语言·c++·stm32·嵌入式硬件·算法
峥无5 小时前
从0到1手撕红黑树:封装实现 my_map 与 my_set(SGI-STL 源码级深度解析)
开发语言·c++·笔记·算法·stl
不会代码的小猴6 小时前
3. 控件学习1
开发语言·c++·笔记·qt·算法
203号居民8 小时前
LeetCode hot 100 —41. 缺失的第一个正数
数据结构·算法·leetcode
专注仿真10 小时前
问答大模型技术方案算法实现-熵权法融合算法 + 交叉编码器重排算法
人工智能·python·算法·语言模型·问答大模型关键算法·熵权融合算法·交叉编码器重排算法
evans在进步10 小时前
LeetCode 322:零钱兑换——Java 动态规划详解
java·leetcode·动态规划
地平线开发者11 小时前
量化为什么会有损失:从量化误差到精度下降
算法
手写码匠11 小时前
华为云Flexus+DeepSeek征文|Dify 多 Agent 会话管理与上下文工程实战:让智能体“记住该记住的,忘掉该忘掉的“
人工智能·深度学习·算法·aigc