宋哥哥


私信TA

用户名:630591905

访问量:8284

签 名:

等  级
排  名 842
经  验 3634
参赛次数 3
文章发表 9
年  龄 0
在职情况 学生
学  校 迦南魔法学院
专  业

  自我简介:

解题思路:
             背包问题,然后需要求最大公约数。

             很容易可以理解,当所有笼包子全部为偶数,比如2,4,6,那完了,有无限多种方案。

             再看一个例子,当全部为3,6,9的时候,能够推出来嘛?也不能,为什么呢?

             好吧,这就要涉及到求最大公约数的问题,第一个例子,公约数为2,第二个公约数为3.


这里直接给出一个结论,当公约数不为1的时候,他们不能组合出来的数,有无限多个,于是用辗转相除法算一下最大公约数即可。


最难理解的是背包,到底状态方程怎么写?


dp[i][j]的意思,前面i个笼子,能不能组合出j,如果能组合出来,dp[i][j]==1,不能组合出来dp[i][j]==0


if(dp[j-arr[i]]==1)dp[j]=1;   这一段是我觉得最难理解的地方,但是想通了就觉得还挺简单的


先来说说,j-arr[i]是什么意思呢?arr[i]里面,存放的是i笼包子存放的包子个数,j-arr[i]就为少一笼包子个数


那么dp[j-arr[i]]又是啥意思,少一笼包子的个数,能不能被组合出来的状态。


我们来看样例,2笼包子,一笼4个,一笼5个。这是我说了,我要吃8个包子,按照这个思路,我们怎么求解?


我是一个懒人,我不想算,那么我就问老板,你可以给我吃4个包子或者3个包子吗?老板说,嗯,我这里一笼有4个,可以给你啊。


4个包子,可以被组合出来,那么8个包子呢,在基础上多加一笼4个包子的 ,不就组合出来了吗。


如果还不理解,我们再看,当我要很多很多包子,但是我还是不想算?这时候,就需要问很多人了


比如20个包子,你问,老板,可以给我16个包子或者15个包子吗?


老板说可以,但是老板也不想算,这时候,他就只好去问他老婆,老婆,可以给我12个包子或者11个包子吗

同时,他又去问他的员工,小明,你可以给我11个包子或者10个包子吗?


我的天哪,他的员工会怎么做,你想一想?依次类推?


那什么人,是可以自己回答的,同时也不需要思考的呢?被问到4笼包子和5笼包子的人,不信你问问我,我直接给你一笼就好了。






注意事项:

参考代码:

       import java.util.Scanner;

public class Main {

		public static void main(String[] args) {
			Scanner in=new Scanner(System.in);
			int n=in.nextInt();//n笼包子
			int arr[]=new int[105];//arr用来存放第i笼包子能容纳的个数
			arr[1]=in.nextInt();//暂时定最大公约数为temp
			int temp=arr[1];
			for(int i=2;i<=n;i++){
				arr[i]=in.nextInt();
				temp=gcd(temp,arr[i]);//最大公约数又temp和下一笼包子的最大公约数
			}
			
			int dp[]=new int[100005];
			dp[0]=1;
			for(int i=1;i<=n;i++){
				for(int j=arr[i];j<100005;j++){
					if(dp[j-arr[i]]==1)dp[j]=1;//如果dp[j-4]或者dp[j-5]都能够表达,那么在基础上,我多放一笼包子就可以了
				}
			}
			int ans=0;
			for(int i=1;i<100005;i++){
				if(dp[i]!=1)ans++;
			}
			if(temp>1)System.out.println("INF");
			else System.out.println(ans);
	}

		private static int gcd(int a, int b) {
			// TODO Auto-generated method stub
			return  b==0?a:gcd(b,a%b);
		}

}


 

0.0分

5 人评分

  评论区

  • «
  • »