dp专题8 1049. 最后一块石头的重量 II

本文介绍了如何通过将问题转化为背包问题来解决LeetCode中的石头相撞问题,利用动态规划找到两堆石头中剩余重量最小的那一堆。关键在于定义dp数组并计算每种情况下石头的最大重量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本题链接:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

题目:

思路:

        由题意,石头的相撞,求最后相撞后剩余的最后一个石头最小的重量是多少。

看到题目的这里,都往取哪些石头的方式去想了,我们不如换个思路,将这堆石头分成两堆,其中一堆尽可能的石头之和,为总石头之和的一半那边靠,然后将这两堆石头相撞,剩余的就一定是重量最小的石头了。

        所以归根结底,还是背包问题,将 总石头之和的一半作为背包容量,另一堆重量 为 sum - dp[sum / 2];   最后相减即可。

代码详解如下:

inline int lastStoneWeightII(vector<int>& stones) 
{
	vector<int>dp(3000,0);	// 定义 dp 数组
	
	int sum = 0;	// 获取石头总重量
	for(int &i:stones) sum += i;
	
	// 获取另一堆重量目标
	int v = sum / 2;
	
	// 开始 dp 过程,取该石头和不取该石头的尽可能最大重量
	for(int &i:stones)
	{
		for(int j = v;j >= i;--j)
		{
			dp[j] = max(dp[j],dp[j - i] + i);
		}
	}
	
	int a = dp[v];	// 一堆石头总重量
	int b = sum - dp[v];	// 另一对的石头总重量
	
	return abs(a - b);	// 返回最后剩余石头的最小重量
}

最后提交:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值