[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 }
View Code

 

posted @ 2017-02-10 10:36  KingSann  阅读(114)  评论(0编辑  收藏  举报