历届试题 包子凑数
小明几乎每天早晨都会在一家包子铺吃早餐。他发现这家包子铺有N种蒸笼,其中第i种蒸笼恰好能放Ai个包子。每种蒸笼都有非常多笼,可以认为是无限笼。
每当有顾客想买X个包子,卖包子的大叔就会迅速选出若干笼包子来,使得这若干笼中恰好一共有X个包子。比如一共有3种蒸笼,分别能放3、4和5个包子。当顾客想买11个包子时,大叔就会选2笼3个的再加1笼5个的(也可能选出1笼3个的再加2笼4个的)。
当然有时包子大叔无论如何也凑不出顾客想买的数量。比如一共有3种蒸笼,分别能放4、5和6个包子。而顾客想买7个包子时,大叔就凑不出来了。
小明想知道一共有多少种数目是包子大叔凑不出来的。
Input
第一行包含一个整数N。(1 <= N <= 100)
以下N行每行包含一个整数Ai。(1 <= Ai <= 100)
Output
一个整数代表答案。如果凑不出的数目有无限多个,输出INF。
Examples
样例输入
2
4
5
样例输出
6
样例输入
2
4
6
样例输出
INF
题意:
题解:
题是很好的题呀…就是数据太水了, dalao们有dalao们扩展欧几里得+完全背包的做法, 做为菜鸡的我暴力就好了
暴力选所有…确定两个范围, 一个是搜索范围, 一个是确定可否得到的范围(也就是超过这个范围依然得不到就认为是所有都得不到了)
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
#define ms(x, n) memset(x,n,sizeof(x));
typedef long long LL;
const int inf = 1<<30;
const LL maxn = 110;
int N, a[maxn], maxN = 0;
bool is[maxn*maxn];
void Dfs(int i, int n){
//当前选第i个, 总和n
is[n] = true;
for(int j = 1; j <= N; j++)
if(!is[n+a[j]] && n+a[j]<=maxN)
Dfs(j, n+a[j]);
}
int solve(){
ms(is, 0);
maxN *= maxN;
for(int i = 1; i <= N; i++)
if(!is[a[i]] && a[i]<=maxN)
Dfs(i, a[i]);
int ret = 0;
for(int i = 1; i < maxN; i++){
if(!is[i] && i>a[1]*a[N]) return -1; //超出这个范围依然有取不到的可以认为是INF
if(!is[i]) ret++;
}
return ret;
}
int main()
{
cin >> N;
bool even = true, odd = true;
for(int i = 1; i <= N; i++){
cin >> a[i];
maxN = max(a[i], maxN);
if(a[i]%2==0) odd = false;
else if(a[i]%2!=0) even = false;
}
//是否都是奇数/偶数
int ans = solve();
if(even || odd || ans==-1) cout << "INF" << endl;
else cout << ans << endl;
return 0;
}