生成函数入门题汇总
很早以前便筹划着看生成函数,直到现在才有足够的效率去理解生成函数问题。
生成函数在我看来可以参考二项式系数的推导过程,保平上课讲二项式系数的时候使用的那个简略证明,我认为对于理解生成函数不错。
有些题目用生成函数或排列组合貌似都可做,可以探究一下。
一个生成函数:
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\n",a1[n]);
40 }
41 return 0;
42 }
入门水题。
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\n",a1[n]);
41 }
42 return 0;
43 }
入门水题。
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\n",i);break;}
45 }
46 return 0;
47 }
入门水题。
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\n",i>limit-i?i:limit-i,i<limit-i?i:limit-i);break;}
41 }
42 return 0;
43 }
入门水题。
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\n",i,(fast(4,x-1,100)+fast(2,x-1,100))%100);
34 }
35 printf("\n");
36 }
37 return 0;
38 }
指数级生成函数,用泰勒展开化简。
考场做法是打表找规律,或者搞出出dp式后用矩阵乘法快速幂。
具体的就不搬运了...
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*(n+1)%mod*(n+2)%mod*fast(6,mod-2,mod)%mod);
34 return 0;
35 }
一道纯数学题,本人数学不好,就不献丑了...