[hdu1085]Holding Bin-Laden Captive!
卷积计数。
将所有面值的硬币写成多项式形式,用系数表示硬币个数,用指数表示硬币面值,则卷积一遍后系数相加,相同系数的式子累积,则再扫一遍后第一个系数为0的位置的系数便是答案。

1 #include <iostream> 2 #include <algorithm> 3 #include <cstdio> 4 #include <cstring> 5 #include <cstdlib> 6 #include <string> 7 #include <vector> 8 #include <cmath> 9 #include <queue> 10 #include <complex> 11 #include <set> 12 using namespace std; 13 14 const int N=16000; 15 16 typedef complex<double> c; 17 18 c c1[N],c2[N],c3[N],F[N]; 19 20 int rev(int x,int n){ 21 int ret=0; 22 for(int i=0;(1<<i)<n;i++)ret=(ret<<1)|((x&(1<<i))>0); 23 return ret; 24 } 25 26 void fft(c *a,int n,int f){ 27 for(int i=0;i<n;i++)F[rev(i,n)]=a[i]; 28 for(int i=2;i<=n;i*=2){ 29 c wn=c(cos(2*acos(-1)*f/i),sin(2*acos(-1)*f/i)); 30 for(int j=0;j<n;j+=i){ 31 c w=1; 32 for(int k=j;k<j+i/2;k++){ 33 c u=F[k],t=w*F[k+i/2]; 34 F[k]=u+t; 35 F[k+i/2]=u-t; 36 w*=wn; 37 } 38 } 39 } 40 for(int i=0;i<n&&f==-1;i++)F[i]/=n; 41 for(int i=0;i<n;i++)a[i]=F[i]; 42 } 43 44 int n1,n2,n3,n; 45 46 int main(){ 47 while(~scanf("%d%d%d",&n1,&n2,&n3)&&(n1||n2||n3)){ 48 n=1; 49 while(n<=n1*1+n2*2+n3*5+10)n<<=1; 50 for(int i=0;i<n;i++)c1[i]=c2[i]=c3[i]=0; 51 for(int i=0;i<=n1;i++)c1[i*1]=1; 52 for(int i=0;i<=n2;i++)c2[i*2]=1; 53 for(int i=0;i<=n3;i++)c3[i*5]=1; 54 55 fft(c1,n,1),fft(c2,n,1),fft(c3,n,1); 56 for(int i=0;i<n;i++)c1[i]=c1[i]*c2[i]*c3[i]; 57 fft(c1,n,-1); 58 for(int i=0;i<n;i++){ 59 if(int(c1[i].real()+0.5)==0){ 60 printf("%d\n",i); 61 break; 62 } 63 } 64 } 65 }