包子凑数(裴蜀定理)

题目链接

下图和题目无关,找解析时找到的小东西而已

对于未知数为 x , y 的式子

当且仅当 M 为 gcd( a , b ) 的整数倍时,方程有整数解(注意是整数解,不是正整数解)

所以当 gcd( a , b )== 1 时,因为所有整数都是 1 的倍数,所以所有正整数都能被 a ,
b 线性表示 、 而 gcd( a , b )> 1 时,集合 M 就会有空缺,有无数个不能表示的数

当 gcd( a , b )== 1 时,只能得到方程有整数解的结论,不能保证解时正整数

但是不能用正整数表示的解 是有上界的(具体怎么求不知道啊qwq,好像可以求 所有数的和的平方,但是实际上会大很多)

确定一个上界后 完全背包dp 就行了

#include <bits/stdc++.h>
using namespace std;
typedef long long int LL;
const int N=110,M=1e5+10;
LL n,ans,a[N],dp[M],GCD,sj;

LL gcd(int a,int b)
{
	while(b^=a^=b^=a%=b);
	return a;
}

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0);
	cin>>n;
	if(n==1)
	{
		cin>>a[1];
		if(a[1]!=1)
		{
			cout<<"INF";
			return 0;
		}
		else cout<<0;
	}
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
		sj+=a[i];
		if(i==1)
		{
			GCD=a[i];
		}
		else
		{
			GCD=gcd(GCD,a[i]);
		}
	}
	if(GCD>1)
	{
		cout<<"INF";
		return 0;
	}
	sj*=sj;
	dp[0]=1;
	for(int i=1;i<=n;i++)
	{
		for(int j=a[i];j<=M;j++)
		{
			dp[j]=max(dp[j],dp[j-a[i]]);
		}
	}
	
	for(int i=1;i<=M;i++)
	{
		if(dp[i]==0) ans++;
	}
	cout<<ans;
	return 0;
}

posted @ 2025-03-24 20:12  石磨豆浆  阅读(15)  评论(0)    收藏  举报