//题外话:好久没更了,最近恢复更新,然后每天写点
//难度划分:易
题目描述:
![](https://i-blog.csdnimg.cn/blog_migrate/9a913a5f2accf163d84f55202695cd24.png)
输入:
![](https://i-blog.csdnimg.cn/blog_migrate/4dceb54262aafd5a7e6a3678a96959d1.png)
输出:
![](https://i-blog.csdnimg.cn/blog_migrate/d79deca1c4ac8d07b9b6c16c130588f6.png)
样例输入:
2
4
5
样例输出:
6
思路
根据扩展欧几里得(塞瓦维斯特定理),ax+by=gcd(a,b),如果gcd(a,b)不为1,则必然有INF个数不能由a和b构成;如果gcd(a,b)为1,则由a和b不能构成的最大的数为a*b-a-b。然后因为题上a[i]<=100,所以最大也就是1e4。然后就可以用bitset或者dp处理。(本人很喜欢bitset,就用bitset写了)
代码(原创)
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int mx = 3e4 + 5;
bitset<mx>can;
signed main() {
int n;
cin >> n;
int a[n];
for (int i = 0; i < n; i++) {
cin >> a[i];
}
if (n == 1) {
if (a[0] == 1)
cout << 0 << endl;
else
cout << "INF" << endl;
} else {
int gc = __gcd(a[0], a[1]);
for (int i = 2; i < n; i++) {
gc = __gcd(a[i], gc);
}
if (gc != 1)
cout << "INF" << endl;
else {
can[0] = true;
for (int i = 0; i < n; i++) {
int t = a[i];
while (t <= 3e4) {
can |= (can << t);
t += a[i];
}
}
int cnt = 0;
for (int i = 0; i <= 3e4; i++) {
if (can[i] == 0)
cnt++;
}
cout << cnt << endl;
}
}
}
代码(dp)
const int maxn=10010;
int main()
{
int i,b,j,res=0;
while(cin>>n)
{
for(i=0;i<n;i++)
cin>>a[i];
b=a[0];
for(i=1;i<n;i++)
b=__gcd(b,a[i]);
if(b!=1)
{
cout<<"INF"<<endl;
continue;
}
for(i=0;i<n;i++)
for(j=0;j+a[i]<maxn;j++)
{
if(ad[j]!=0)
ad[j+a[i]]=1;
}
for(i=0;i<maxn;i++)
if(ad[i]==0)
res++;
cout<<res<<"\n";
}
return 0;
}