贪心算法解决数的补充最优解的问题||补丁数组

该博客介绍了一个使用贪心算法解决的数学问题,即如何在有序非负整数列中添加最少的数,使得能用这些数的和表示[1, n]之间的所有整数。博客给出了问题描述、输入输出格式,并分享了C++实现的贪心算法思路和代码。" 132961380,18148785,无参考图像质量评价的反卷积去模糊算法与Matlab实现,"['计算机视觉', '图像处理', 'Matlab', '算法', '数字图像处理']

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

补丁数组|Turing


Description

 

给定一个长度为l的有序非负整数列nums和一个整数n,最少需要添加多少个数可以使得[1,n]间的每一个数都可以被数列中

若干个数的和来表示。(数组中的元素不能重复使用)

输出最少需要添加多少个数字。

 

Input

 

共计两行。

第一行:两个整数l和n,分别代表数列nums的长度和整数n。(l不大于10^5,n不大于INT_MAX)

第二行:n个有序非负整数。(每个数不大于10^4)

 

Output

 

最少需要添加的数字个数。

 

输入样例 1 

2 6
1 3

输出样例 1


1
​​​​​​​

Combinations of nums are [1], [3], [1,3], which form possible sums of: 1, 3, 4.
Now if we add/patch 2 to nums, the combinations are: [1], [2], [3], [1,3], [2,3], [1,2,3].
Possible sums are 1, 2, 3, 4, 5, 6, which now covers the range [1, 6].
So we only need 1 patch.
nums的组合是[1],[3],[1,3],它们形成可能的总和:1,3,4。
现在,如果我们将/补丁2添加到nums,则组合为:[1],[2],[3],[1,3],[2,3],[1,2,3]。
可能的总和是1,2,3,4,5,6,现在涵盖范围[1,6]。
所以我们只需要1个补丁。

输入样例 2 

3 20
1 5 10

输出样例 2

2

The two patches can be [2, 4].
这两个补丁可以是[2,4]。

输入样例 3 

3 5
1 2 2

输出样例 3

0

Language: 

C++

思想

 

本题需采用贪心算法,试让使用的补丁最少,且能覆盖范围内的所有值,达到最简的目的。

最开始首先想象到的就是依次枚举题目给定数组之外的数,并判断是否满足条件。但是细读题目可以发现(l不大于10^5,

n不大于INT_MAX),l的范围可以接受,但是n的范围开数组是肯定超出题目限制了,会Runtime Error 或者是Time limit

exceed。

所以穷举是肯定不行了,我们就改变下思路,每次判断的位置后移,判断当前位置的数加上前置和是否会超出题目的n的

范围,如果没有,就继续,再判断一下是否这个和满足了当前范围,其中没有数的遗漏,如果有,就再申请一个适当的数

并进行判断。直到和sum>=n,就break

 

代码

#include<cstdio>
int main()
{
	int n,i,j,l,nums[100005],sum=0,ans=0,wz=1;
	scanf("%d%d",&l,&n);
	for(i=1;i<=l;i++)
		scanf("%d",&nums[i]);
	for(;;)
	{
		if(sum>=n)
			break;
		for(;;)
			if(wz<=l&&nums[wz]<=sum)
				sum+=nums[wz++];
			else
				break;
		if(wz<=l&&nums[wz]==sum+1)
			wz++;
		else
			ans++;
	}
	printf("%d",ans);
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值