思路: 当正整数A与B互质时,用A和B凑不出的最大数为 A×B-A-B 。 也就是说A×B-A-B+1后的数都是可以凑出来的。
对于这道题本质是求\(a_1×x+a_2×y+...+a_n×z=x\) 由exgcd可知当\(x=k×gcd(a_1,a_2,...,a_n)\)时有解,如答案不是inf,说明在某个数后面的所有数作为x都有解,对于一些连续的数,最大公约数只能是1,所以\(gcd(a_1,a_2,...,a_n)!=1\)时解为inf.
对于由于上面的定理可知,两个数最大凑不出的数最多也才\(a_i*a_j\),所以直接去上界为100*100,然后利用完全背包统计。
#include<bits/stdc++.h>
using namespace std;
const int N=110;
int a[N],f[N*N];
int main(){
int n;
cin>>n;
memset(f,0,sizeof f);
int g=-1;
for(int i=1;i<=n;++i) {
cin>>a[i];
if(g==-1) g=a[i];
else g=__gcd(g,a[i]);
}
if(g!=1){
cout<<"INF\n";
return 0;
}
f[0]=1;
for(int i=1;i<=n;++i){
for(int j=a[i];j<=N*N-1;++j){
f[j]+=f[j-a[i]];
}
}
int flag=0;
for(int i=N*N-1;i>=0;--i){
if(!f[i]) flag++;
}
if(!flag) cout<<"0\n";
else cout<<flag<<endl;
return 0;
}
P6188 [NOI Online 入门组]文具订购
思路: 利用上面的定理,3,4,7凑不出的最大数是5,在枚举下也就是(1,2,5)是凑不出的,那么所以保证n不等于这些数的前提下,尽量整套买,我们发现整套买完后最大的剩余钱数是19,因为大于20可以再买一套后剩余钱数大于5也是可以凑的。最后n<19枚举a,b,c可以凑时最大的a+b+c。
#include<bits/stdc++.h>
using namespace std;
int main(){
int a=0,b=0,c=0;
int n;
cin>>n;
if(n<=5) {
if(n==3){
cout<<"0 0 1\n";
}
else if(n==4){
cout<<"0 1 0\n";
}
else if(n==0)
cout<<"0 0 0\n";
else
cout<<"-1\n";
return 0;
}
int t=n/14;t++;
n-=14*t;
while(t>0&&(n<=5&&n!=0&&n!=3&&n!=4)) t--,n+=14;
int t2=0;
for(int i=0;i<15;++i){
for(int j=0;j<15;++j){
for(int k=0;k<15;++k){
if(i*7+j*4+k*3==n){
if(i+j+k>t2){
a=i,b=j,c=k;
t2=i+j+k;
}
}
}
}
}
cout<<a+t<<" "<<b+t<<" "<<c+t<<endl;
return 0;
}