题目
https://www.luogu.com.cn/problem/P2737
思路
裴蜀定理:方程(sum_{i=1}^{n}k_ix_i=b)有整数解当且仅当(gcd(k_1,k_2,...,k_n)|b)
不知道的同学可以做一下这题:【模板】裴蜀定理
证明:
必要性
设 (gcd(k_1,k_2,...,k_n)=g)(后面也用g表示),则 (g|k1,g|k2....),又(b=sum_{i=1}^{n}k_ix_i),所以(g|b)。
充分性
先证方程(sum_{i=1}^{n}k_ix_i=g)有解,当(n=2)时根据扩展欧几里得算法显然成立,利用数学归纳法,假设(n=k)时方程有解,那么(n=k+1)时:
(k_1x_1+k_2x_2+....+k_nx_n+k_{n+1}x_{n+1}=gcd(k_{n+1},g)),就要证存在(x_{n+1}) 使 (k_{n+1}x_{n+1}+lambda g=gcd(k_{n+1},g))
解释一下(lambda g),这是说因为 (k=n) 时方程有解,所以我们将解中的每一个(x)变为原来的 (lambda) 倍,就使得(sum_{i=1}^{n}k_ix_i=lambda g),其中 (lambda) 是任意整数。
那么,改写一下 (k=n+1)时的方程 :(ax+by=gcd(a,b)),肯定有解。
所以方程(sum_{i=1}^{n}k_ix_i=g)有解,又因为(g|b),所以我们将方程(sum_{i=1}^{n}k_ix_i=g) 的解变为原来的(frac{b}{g})倍就可以了。
综上,裴蜀定理得证。
解决问题
分析一下,这道题就是要找一个最大的(b),使得方程 (sum_{i=1}^{n}k_ix_i=b) 无自然数解。
根据裴蜀定理,如果(g>1),可以找到一个任意大的(b)((g mid b)),使该方程没有整数解,自然更没有自然数解了,输出"0"。
如果(g=1),方程一定存在整数解,且(b)足够大时,一定能通过解的调整使各个(x)都变为自然数,所以满足题意的 (b) 是有上界的。
我们关心的是这个上界是多少。我太弱了不会证,那就开个1e6的数组试试吧,接下来跑DP就完事了。
然后,过了。。。
代码
#include<cstdlib>
#include<algorithm>
using namespace std;
int dp[1000000],a[11];
int gcd(int x,int y){
if(x<y) swap(x,y);
if(!y) return x;
return gcd(y,x%y);
}
int main(){
int n,i,j,ans=0,g=0;
scanf("%d",&n);
for(i=1;i<=n;i++){
scanf("%d",&a[i]);
g=gcd(g,a[i]);
}
dp[0]=1;
for(i=1;i<=1000000;i++){
for(j=1;j<=n;j++){
if(i>=a[j])
dp[i]|=dp[i-a[j]];
}
if(!dp[i]) ans=i;
}
if(g==1) printf("%d",ans);
else printf("0");
system("pause");
return 0;
}
补充
如果想进一步看看上界的值怎么算的巨佬请移步rqy小姐姐的博客https://www.luogu.com.cn/blog/rqy/solution-p2737