生成函数入门题汇总

很早以前便筹划着看生成函数,直到现在才有足够的效率去理解生成函数问题。

生成函数在我看来可以参考二项式系数的推导过程,保平上课讲二项式系数的时候使用的那个简略证明,我认为对于理解生成函数不错。

有些题目用生成函数或排列组合貌似都可做,可以探究一下。

一个生成函数:

1+x+x2+x3+...

系数代表方案数,指数代表状态,运算即代表状态的推导。

一种不错的状态表示方法?

Ignatius and the Princess III hdu1028  

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<cstring>
 5 #include<ctime>
 6 #include<cmath>
 7 #include<algorithm>
 8 #include<iomanip>
 9 #include<queue>
10 #include<set>
11 using namespace std;
12 #define LL long long
13 #define FILE "dealing"
14 #define mid ((l+r)>>1)
15 #define pii pair<LL,LL>
16 #define up(i,j,n) for(LL i=(j);i<=(n);i++)
17 LL read(){
18     LL x=0,f=1,ch=getchar();
19     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
20     while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
21     return f*x;
22 }
23 const LL maxn=1010,inf=1000000000;
24 LL a1[maxn],a2[maxn],a3[maxn],n;
25 int main(){
26     //freopen(FILE".in","r",stdin);
27     //freopen(FILE".out","w",stdout);
28     while(scanf("%lld",&n)!=EOF){
29         up(i,0,n)a1[i]=1;
30         up(i,2,n){
31             memset(a3,0,sizeof(a3));
32             memset(a2,0,sizeof(a2));
33             for(int j=0;j<=n;j+=i)a2[j]=1;
34             for(int j=0;j<=n;j++)
35                 for(int k=0;k+j<=n;k++)
36                     a3[j+k]+=a1[j]*a2[k];
37             up(j,0,n)a1[j]=a3[j];
38         }
39         printf("%lld
",a1[n]);
40     }
41     return 0;
42 }
View Code

入门水题。

Square Coins  hdu1398

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<cstring>
 5 #include<ctime>
 6 #include<cmath>
 7 #include<algorithm>
 8 #include<iomanip>
 9 #include<queue>
10 #include<set>
11 using namespace std;
12 #define LL long long
13 #define FILE "dealing"
14 #define mid ((l+r)>>1)
15 #define pii pair<LL,LL>
16 #define up(i,j,n) for(LL i=(j);i<=(n);i++)
17 LL read(){
18     LL x=0,f=1,ch=getchar();
19     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
20     while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
21     return f*x;
22 }
23 const LL maxn=1010,inf=1000000000;
24 LL a1[maxn],a2[maxn],a3[maxn],n;
25 int main(){
26     freopen(FILE".in","r",stdin);
27     freopen(FILE".out","w",stdout);
28     while(true){
29         n=read();if(!n)return 0;
30         up(i,0,n)a1[i]=1;
31         for(int i=2;i*i<=n&&i<=17;i++){
32             memset(a3,0,sizeof(a3));
33             memset(a2,0,sizeof(a2));
34             for(int j=0;j<=n;j+=i*i)a2[j]=1;
35             for(int j=0;j<=n;j++)
36                 for(int k=0;k+j<=n;k++)
37                     a3[j+k]+=a1[j]*a2[k];
38             up(j,0,n)a1[j]=a3[j];
39         }
40         printf("%lld
",a1[n]);
41     }
42     return 0;
43 }
View Code

入门水题。

Holding Bin-Laden Captive!

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<cstring>
 5 #include<ctime>
 6 #include<cmath>
 7 #include<algorithm>
 8 #include<iomanip>
 9 #include<queue>
10 #include<set>
11 using namespace std;
12 #define LL long long
13 #define FILE "dealing"
14 #define mid ((l+r)>>1)
15 #define pii pair<int,int>
16 #define up(i,j,n) for(int i=(j);i<=(n);i++)
17 int read(){
18     int x=0,f=1,ch=getchar();
19     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
20     while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
21     return f*x;
22 }
23 const int maxn=10100,inf=1000000000;
24 int a1[maxn],a2[maxn],a3[maxn],num[maxn],v[maxn],n;
25 int main(){
26     freopen(FILE".in","r",stdin);
27     freopen(FILE".out","w",stdout);
28     v[1]=1;v[2]=2;v[3]=5;
29     int limit=0;
30     while(~scanf("%d%d%d", &num[1], &num[2], &num[3]) && (num[1] || num[2] || num[3])){
31         limit=num[1];
32         memset(a1,0,sizeof(a1));
33         up(i,0,num[1])a1[i]=1;
34         up(i,2,3){
35             memset(a3,0,sizeof(a3));
36             memset(a2,0,sizeof(a2));
37             up(j,0,num[i])a2[j*v[i]]=1;
38             for(int j=0;j<=limit;j++)
39                 for(int k=0;k<=num[i]*v[i];k++)
40                     a3[j+k]+=a1[j]*a2[k];
41             limit+=num[i]*v[i];
42             up(j,0,limit)a1[j]=a3[j];
43         }
44         up(i,0,limit+1)if(!a1[i]){printf("%d
",i);break;}
45     }
46     return 0;
47 }
View Code

入门水题。

Big Event in HDU

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<cstring>
 5 #include<ctime>
 6 #include<cmath>
 7 #include<algorithm>
 8 #include<iomanip>
 9 #include<queue>
10 #include<set>
11 using namespace std;
12 #define LL long long
13 #define FILE "dealing"
14 #define mid ((l+r)>>1)
15 #define pii pair<int,int>
16 #define up(i,j,n) for(int i=(j);i<=(n);++i)
17 int read(){
18     int x=0,f=1,ch=getchar();
19     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
20     while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
21     return f*x;
22 }
23 const int maxn=250010,inf=1000000000;
24 int num[maxn],v[maxn],c[maxn],c2[maxn],n;
25 int main(){
26     freopen(FILE".in","r",stdin);
27     freopen(FILE".out","w",stdout);
28     while(true){
29         memset(c,0,sizeof(c));
30         memset(c2,0,sizeof(c));
31         n=read();if(n<=0)break;
32         up(i,1,n)v[i]=read(),num[i]=read();
33         int limit=v[1]*num[1];
34         for(int i=0;i<=limit;i+=v[1])c[i]=1;
35         up(i,2,n){
36             for(int k=0;k<=limit;k++)for(int j=0;j<=v[i]*num[i];j+=v[i])c2[j+k]+=c[k];
37             limit+=v[i]*num[i];
38             up(j,0,limit)c[j]=c2[j],c2[j]=0;
39         }
40         for(int i=limit/2;i<=limit;i++)if(c[i]){printf("%d %d
",i>limit-i?i:limit-i,i<limit-i?i:limit-i);break;}
41     }
42     return 0;
43 }
View Code

入门水题。

"红色病毒"问题

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<cstring>
 5 #include<ctime>
 6 #include<cmath>
 7 #include<algorithm>
 8 #include<iomanip>
 9 #include<queue>
10 #include<set>
11 using namespace std;
12 #define LL long long
13 #define FILE "dealing"
14 #define mid ((l+r)>>1)
15 #define pii pair<LL,LL>
16 #define up(i,j,n) for(LL i=(j);i<=(n);++i)
17 LL read(){
18     LL x=0,f=1,ch=getchar();
19     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
20     while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
21     return f*x;
22 }
23 const LL maxn=250010,inf=1000000000;
24 LL fast(LL a,LL b,LL c){LL ans=1;for(;b;a=a*a%c,b>>=1)if(b&1)ans=ans*a%c;return ans;}
25 int main(){
26     //freopen(FILE".in","r",stdin);
27     //freopen(FILE".out","w",stdout);
28     LL T=0;
29     while(true){
30         T=read();if(!T)return 0;
31         up(i,1,T){
32             LL x=read();
33             printf("Case %lld: %lld
",i,(fast(4,x-1,100)+fast(2,x-1,100))%100);
34         }
35         printf("
");
36     }
37     return 0;
38 }
View Code

指数级生成函数,用泰勒展开化简。

考场做法是打表找规律,或者搞出出dp式后用矩阵乘法快速幂。

具体的就不搬运了...

【bzoj3028】食物 母函数+乘法逆元

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<cstring>
 5 #include<ctime>
 6 #include<cmath>
 7 #include<algorithm>
 8 #include<iomanip>
 9 #include<queue>
10 #include<set>
11 using namespace std;
12 #define LL long long
13 #define FILE "dealing"
14 #define mid ((l+r)>>1)
15 #define pii pair<LL,LL>
16 #define up(i,j,n) for(LL i=(j);i<=(n);++i)
17 LL read(){
18     LL x=0,f=1,ch=getchar();
19     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
20     while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
21     return f*x;
22 }
23 const LL maxn=501,inf=1000000000,mod=10007;
24 LL fast(LL a,LL b,LL c){LL ans=1;for(;b;a=a*a%c,b>>=1)if(b&1)ans=ans*a%c;return ans;}
25 char s[maxn];
26 LL n=0,len=0;
27 int main(){
28     freopen(FILE".in","r",stdin);
29     freopen(FILE".out","w",stdout);
30     scanf("%s",s+1);
31     len=strlen(s+1);
32     up(i,1,len)n=((n<<1)+(n<<3)+s[i]-'0')%mod;
33     printf("%lld
",n*(n+1)%mod*(n+2)%mod*fast(6,mod-2,mod)%mod);
34     return 0;
35 }
View Code

一道纯数学题,本人数学不好,就不献丑了...

原文地址:https://www.cnblogs.com/chadinblog/p/6406135.html