[数论,完全背包]包子凑数

题目

​链接:包子凑数​

思路:
根据贝祖(裴蜀)定理,两个数x,y能凑出的数一定是gcd(x,y)的倍数。因此如果gcd(x,y)!=1一定有无限个凑不出来的数,这个可以推广到n个数
而当gcd(x,y)==1的时候,就有有限个凑不出来的数
既然有限的话那么到一定上限就都能凑出来了我们对0~max进行属性为是否可以凑出来的完全背包dp

定义f[i][j]为从前i个物品中选体积恰好为j的完全背包问题

[数论+完全背包]包子凑数_#include

代码

#include<bits/stdc++.h>
using namespace std;
const int N=110,MAX_N=1e4+10;
int n;
int a[N];
bool dp[MAX_N];//前i个物品中选,体积恰好为j是否可以
int gcd(int a,int b)
{
return b?gcd(b,a%b):a;
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)cin>>a[i];
if(n==1)printf("INF");
else
{
int d=gcd(a[1],a[2]);
for(int i=3;i<=n;i++)d=gcd(a[i],d);
if(d!=1)printf("INF");
else
{
int res=0;
dp[0]=1;
for(int i=1;i<=n;i++)
for(int j=a[i];j<=MAX_N;j++)
dp[j]=dp[j]||dp[j-a[i]];
for(int i=0;i<=MAX_N;i++)res+=!dp[i];
printf("%d",res);
}
}
return 0;
}