2017藍橋杯C/C++A組省賽包子湊數(輾轉相除法和完全背包)


答案:

#include<bits/stdc++.h>
using namespace std;

bool judge(int x,int y)
{
int t;
while(y>0)
{
t=x%y;
x=y;
y=t;
}
if(x==1)
return true;
return false;
}

int a[110],n;
bool dp[10010];
int main()
{
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%d",&a[i]);
int flag=0;
for(int i=0;i<n;i++)
{
for(int j=1;j<=n;j++)
{
if(judge(a[i],a[j]))
{
flag=1;
break;
}
}
if(flag==1)
break;
}
if(flag!=1)
{
printf("INF\n");
return 0;
}
dp[0]=1;
for(int i=0;i<n;i++)
{
for(int j=0;j+a[i]<10000;j++)
if(dp[j])
dp[j+a[i]]=1;
}
int ans=0;
for(int i=0;i<10000;i++)
{
if(dp[i]!=1)
ans++;
}
printf("%d\n",ans);
return 0;
}


預備知識

輾轉相除法

(原理:假設有兩個數x和y,存在一個最大公約數z=(x,y),即x和y都有公因數z,
那么x一定能被z整除,y也一定能被z整除,所以x和y的線性組合mx±ny也一定能被z整除。(m和n可取任意整數)
對於輾轉相除法來說,思路就是:若x>y,設x/y=n余c,則x能表示成x=ny+c的形式,將ny移到左邊就是x-ny=c,由於一般形式的mx±ny能被z整除,所以等號左邊的x-ny(作為mx±ny的一個特例)就能被z整除,即x除y的余數c也能被z整除。

(以下是挑戰程序設計競賽的內容)

1.求最大公約數

例題:線段上格點的個數

。。。。。

3.擴展歐幾里得算法

對輾轉相除法做一下擴展

例題:雙六

這個問題用數學語言表述就是“求整數X和Y使得ax+bt=1”.可以發現,如果gcd(a,b)!=1,則無解,反之,如果gcd(a,b)=1,就可以通過擴展原來的輾轉相除法來求解。事實上,一定存在整數對(x,y)使得ax+by=gcd(a,b),並可以用同樣的算法求得

int extgcd(int a,int b,int& x,int& y)
{
int d=a;
if(b!=0)
{
d=extgcd(b,a%b,y,x);
y=y-(a/b)*x;
}
else
{
x=1;
y=0;
}
return d;
}






注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com