問題描述
小明幾乎每天早晨都會在一家包子鋪喫早餐。他發現這家包子鋪有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;
}