解题思路:
背包问题,然后需要求最大公约数。
很容易可以理解,当所有笼包子全部为偶数,比如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 人评分
简单的a+b (C语言代码)浏览:765 |
C语言程序设计教程(第三版)课后习题10.2 (C语言代码)浏览:1055 |
【偶数求和】 (C++代码)浏览:785 |
C语言程序设计教程(第三版)课后习题5.4 (C语言代码)浏览:1327 |
2003年秋浙江省计算机等级考试二级C 编程题(2) (C语言代码)浏览:690 |
简单的a+b (C语言代码)浏览:752 |
C语言程序设计教程(第三版)课后习题7.2 (C语言代码)浏览:686 |
Tom数 (C语言代码)浏览:598 |
妹子杀手的故事 (C语言代码)浏览:1153 |
模拟计算器 (C语言代码)浏览:2366 |