vlambda博客
学习文章列表

力扣 1049题 动态规划

力扣 1049题 动态规划

推荐使用语雀阅读[1],因为有 LaTex 公式,其他方式排版不好。


image.png

最终还是回到了我的老本行[2],写题解。人生就像一场马拉松,跑得快很厉害,跑得远也很重要。


题目描述


力扣 1049题 动态规划
image.png



力扣 1049题 动态规划
image.png


解题思路

推荐阅读背包九讲[3],本题用到其中的第一部分,01 背包。因为每两块石头就能粉碎,可以试着把这些石头分为两份,分别为 a 份和 b 份,如果想要剩下的数字尽量小,那就要让 a 份和 b 份尽量相等,如果完全相等,那是最好的,这样答案就为 0,因为 a 份和 b 份总能全部抵消。那如果只看 a 份,就可以转换为:把这些石头放进一个容量为

力扣 1049题 动态规划

的背包中,尽量放最多,这就让我们想到了什么,是 01 背包:



力扣 1049题 动态规划
image.png


只不过在当前情景下

力扣 1049题 动态规划

问题就转换为,有一个容量为

力扣 1049题 动态规划

的背包,放入第 i 件物品的费用是

力扣 1049题 动态规划

得到的价值还是

力扣 1049题 动态规划

求价值最大,我们可以使用优化后的方式来编写代码:



力扣 1049题 动态规划
image.png


时间复杂度是

力扣 1049题 动态规划

代码如下:(本代码使用了 Lodash,因为力扣已经默认包含了这个库)


var lastStoneWeightII = function(stones) { const sSum = _.sum(stones); const n = stones.length; const volume = Math.floor(sSum / 2);
const dp = Array(volume + 1).fill(0);
for (let i = 0; i < n; i++) { const tmp = stones[i]; for (let j = volume; j >= tmp; j--) { dp[j] = Math.max(dp[j], dp[j - tmp] + tmp); } }
return sSum - dp[volume] * 2;};


image.png


结语

最开始我也没有想到用一半的容量去跑 01 背包,看了别人的代码才知道,我一开始就想偏了,还是挺难的 😂


image.png


引用链接

[1] 语雀阅读: https://www.yuque.com/zcue/dev-blog/pyv79e
[2] 老本行: https://www.cnblogs.com/s1124yy/
[3] 背包九讲: https://github.com/tianyicui/pack
[4] GitHub: https://github.com/Acmu
[5] 掘金: https://juejin.im/user/5bcab884e51d450e81091745
[6] 语雀: https://www.yuque.com/zcue/dev-blog