試題 歷屆試題 包子湊數

問題描述
  小明幾乎每天早晨都會在一家包子鋪喫早餐。他發現這家包子鋪有N種蒸籠,其中第i種蒸籠恰好能放Ai個包子。每種蒸籠都有非常多籠,可以認爲是無限籠。

每當有顧客想買X個包子,賣包子的大叔就會迅速選出若干籠包子來,使得這若干籠中恰好一共有X個包子。比如一共有3種蒸籠,分別能放3、4和5個包子。當顧客想買11個包子時,大叔就會選2籠3個的再加1籠5個的(也可能選出1籠3個的再加2籠4個的)。

當然有時包子大叔無論如何也湊不出顧客想買的數量。比如一共有3種蒸籠,分別能放4、5和6個包子。而顧客想買7個包子時,大叔就湊不出來了。

小明想知道一共有多少種數目是包子大叔湊不出來的。
輸入格式
  第一行包含一個整數N。(1 <= N <= 100)
  以下N行每行包含一個整數Ai。(1 <= Ai <= 100)
輸出格式
  一個整數代表答案。如果湊不出的數目有無限多個,輸出INF。
樣例輸入

2
4
5

樣例輸出

6

樣例輸入

2
4
6

樣例輸出

INF

樣例說明
  對於樣例1,湊不出的數目包括:1, 2, 3, 6, 7, 11。
  對於樣例2,所有奇數都湊不出來,所以有無限多個。
沒解決好的地方是多個數是否有解。開始學過兩個數互質的話最大不能組成的數是a*b-a-b,有多個數就不適用了,應該用兩個數的最大公約數與別的數求最大公約數。最後不是1的話取一個較大的值來求,可以dfs也可以萬全揹包求。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
#include<map>
using namespace std;
const int N=110;
const int inf=0x3f3f3f3f;
int a[N],n,tot,dp[N*N];
int gcd(int a,int b){
	return b==0?a:gcd(b,a%b);
}
void dfs(int start,int x){
	if(tot) return;
	if(!x) {
		tot=1;return;
	}
	for(int i=start;i<n;i++){
		if(a[i]>x) return ;
		dfs(i,x-a[i]);	
	}
}
int main()
{
	int i,j,m,x,y,ans=0,flag=0,ma=0;
	scanf("%d",&n);
	for(i=0;i<n;i++){
		scanf("%d",&a[i]);
		if(!i) flag=a[i];
		else flag=gcd(flag,a[i]);
	}
	if(flag!=1){
		puts("INF");
		return 0;
	}
/*	sort(a,a+n);
	for(i=1;i<=10000;i++){
		tot=0;
		dfs(0,i);
		if(tot) ans++;
	}
	printf("%d",10000-ans);*/
	
	dp[0]=1;
	for(i=0;i<n;i++)
		for(j=a[i];j<10005;j++)
			dp[j]=max(dp[j],dp[j-a[i]]);
	for(i=1;i<10005;i++)
		if(!dp[i]) ans++;
	printf("%d",ans);
	return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章