凑数字游戏

题目描述
小易邀请你玩一个数字游戏,小易给你一系列的整数。你们俩使用这些整数玩游戏。每次小易会任意说一个数字出来,然后你需要从这一系列数字中选取一部分出来让它们的和等于小易所说的数字。 例如: 如果{2,1,2,7}是你有的一系列数,小易说的数字是11.你可以得到方案2+2+7 = 11.如果顽皮的小易想坑你,他说的数字是6,那么你没有办法拼凑出和为6 现在小易给你n个数,让你找出无法从n个数中选取部分求和的数字中的最小数。
输入描述:
输入第一行为数字个数n (n ≤ 20)
第二行为n个数xi (1 ≤ xi ≤ 100000)
输出描述:
输出最小不能由n个数选取求和组成的数
示例1
输入
3
5 1 2
输出

4

没有通过的代码:

import java.util.Scanner;

public class Main {
	static boolean flag=false;
	public static void main(String[] args) {
		Scanner input =new Scanner(System.in);
		int n=input.nextInt();

		int []a=new int[n];
		
		for(int i=0;i<n;i++)
		{
			a[i]=input.nextInt();
		}
		input.close();

		int i=1;
		while(fun(i,a))
		{
			i++;
		}
		System.out.println(i);
	}
	
	static int cnt=0;
	static boolean fun(int n,int ...a)
	{
		cnt=0;
		flag=false;
		find(0,n,a);
		return flag;
	}
	
	static void find(int n,int v,int ...a)
	{
		if(n>=a.length)
			return;
		cnt+=a[n];
		if(cnt==v)
		{
			flag=true;
			return;
		}
		find(n+1,v,a);
		if(flag) return;
		cnt-=a[n];
		find(n+1,v,a);
	}
}
用暴力枚举,未通过,算法复杂度过高。
然后百度发现还有另一种操作:
从小到大排序,一开始一块钱都凑不出来
下面,为了0~x都有,我需要来一个1元的(不然1元凑不出来)
给了你1元的,下面必须给1+1元以内的,不然2元凑不出来
如果再给一个1元的,那你现在能凑出0~2元的,接下来+1+2或者+3,都能增大范围而且不会导致中间缺一个数(4元的不行,因为凑不出3了)
——反正一直往下,直到出现第一个算不出来的值为止。
基于这样一种迭代的思想:我当前假如说可以得到最大的数为k,则再来一个新的数字p,若p<=k+1,则我可以得到的最大的数为p+k,若p>k+1,则会出现空挡,k+1就肯定不能再得到。


于是得到下面的代码:


import java.util.Arrays;
import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner input =new Scanner(System.in);
		int n=input.nextInt();

		int []a=new int[n];
		for(int i=0;i<n;i++)
		{
			a[i]=input.nextInt();
		}
		input.close();
		Arrays.sort(a);
		
		int k=0;
		for(int i=0;i<a.length;i++)
		{
			if(a[i]>k+1) break;
				k+=a[i];
		}
		
		System.out.println(k+1);
	}
}



猜你喜欢

转载自blog.csdn.net/qq_29215513/article/details/78417657