生成函數


生成函數

定義

生成函數又叫母函數,可以看成對代數對象的形式上的處理,利用代數方法計算計數問題,另外也是無限可微函數的冪級數展開式。分為普通生成函數和指數生成函數。

普通生成函數

序列\(h\)的普通生成函數(ordinary generating function,OGF)定義為形式冪級數:

\[g(x) = h_0+h_1x+h_2x^2+\cdots+h_nx^n+\cdots \]

\(h\)既可以是有窮序列,也可以是無窮序列。

例:牛頓二項式定理

\(\alpha\)為實數,二項式系數的無窮數列

\[\binom{\alpha}{0},\binom{\alpha}{1},\binom{\alpha}{2},\cdots,\binom{\alpha}{n},\cdots \]

的生成函數是

\[(1+x)^\alpha = \binom{\alpha}{0}+\binom{\alpha}{1}x+\binom{\alpha}{2}x^2+\cdots+\binom{\alpha}{n}x^n+\cdots \]

封閉形式

\(1,1,1,1\cdots\)的生成函數為\(F(x)=\sum_{i \ge 0} x^i\),可以轉化為

\[F(x) = \frac{1}{1-x} \]

同理,等比數列\(1,p,p^2,p^3,\cdots\)可以表示為\(\frac{1}{1-px}\)

指數生成函數

序列\(h\)的指數生成函數(exponential generating function,EGF)定義為形式冪級數:

\[g(x) = h_0+h_1x+h_2\frac{x^2}{2!}+\cdots+h_n\frac{x^n}{n!}+\cdots \]

\(h\)既可以是有窮序列,也可以是無窮序列。

\(h\)的指數生成函數也可以看成\(\{\hat{h}|\hat{h_i} = \frac{h_i}{i!}\}\)的普通生成函數。

例:\(e^x\)

\(1,1,1,1\cdots\)的指數生成函數為

\[g(x)=\sum_{i=0}^{\infin} \frac{x^i}{i!}=e^x \]

一般地,\(1,a,a^2,a^3,\cdots\)的指數生成函數是

\[g(x)=\sum_{i=0}^{\infin} a^i\frac{x^i}{i!}=e^{ax} \]

用途

普通生成函數——組合

\(h_i\)表示

\[e_1+e_2+\cdots+e_k=n \]

的非負整數解的個數。根據插板法有

\[h_n=\binom{n+k-1}{k-1} (n \geq 0) \]

\(h\)的生成函數是

\[g(x) = \sum_{n=0}^\infin \binom{n+k-1}{k-1}x^n=\frac{1}{(1-x)^k} \]

我們可以理解成是k個\(\frac{1}{1-x}\)乘在一起,也就是

\[x^n=x^{e_1}x^{e_2}\cdots x^{e^k} \]

例:[HDU2152 Fruit][https://vjudge.net/problem/HDU-2152]

答案為

\[\prod_{i=1}^{n} (\sum_{j=a_i}^{b_i} x^j) \]

\(x^m\)系數。

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

const int mn=206;
int n,m,a,b,p[mn],q[mn];

int main()
{
    while(scanf("%d%d",&n,&m)!=EOF) {
        for(int i=0;i<=m;++i) p[i]=0;
        p[0]=1;
        for(int i=1;i<=n;++i) {
            scanf("%d%d",&a,&b);
            for(int j=0;j<=m;++j) q[j]=0;
            for(int j=a;j<=b;++j)
                for(int k=m-j;k>=0;--k) {
                    q[j+k]+=p[k];
                }
            for(int j=0;j<=m;++j) p[j]=q[j];
        }
        printf("%d\n",p[m]);
    }
    return 0;
}

指數生成函數——排列

考慮\(n\)個元素的\(k\)排列的指數生成函數

\[g^{(e)}(x) = P(n,0)+P(n,1)x+P(n,2)\frac{x^2}{2!}+\cdots+P(n,n)\frac{x^n}{n!} \]

其中\(P(n,i) = \frac{n!}{(n-i)!}\)。我們可以發現

\[g^{(e)}(x) = \binom{n}{0}+\binom{n}{1}x+\cdots+\binom{n}{n}x^n \]

是組合數的普通生成函數。

多重集的\(k\)排列

設多重集\(S\)\(\{n_1a_1,n_2a_2,\cdots,n_ka_k\}\),那么其排列為

\[g(x) = \prod_{i=1}^k e^{n_ix} \]

例:[poj3734 Blocks][http://poj.org/problem?id=3734]

推出式子是

\[g(x)=\frac{e^{2n}+2e^{n}+1}{4}\\ h_n = \frac{4^n+2^{n+1}+[n==0]}{4} \]

#include <cstdio>
#define LL long long
#define pb push_back
#define mp make_pair
#define pii pair<int,int>
#define fi first
#define se second
#define lc nd<<1
#define rc nd<<1|1
#define lowbit(x) (x&(-x))
#define pLL pair<LL,LL>

using namespace std;

const int mod=10007;
template<typename T>
T qpow(T a,T b) {LL ans=1;while(b) {if(b&1) ans=ans*a%mod;a=a*a%mod;b>>=1;}return ans;}


const int mn=1e5+6;


int main()
{
    int tests=1;scanf("%d",&tests);
    while(tests--) {
        int n;
        scanf("%d",&n);
        printf("%lld\n",1ll*(qpow(4,n)+qpow(2,n+1))*qpow(4,mod-2)%mod);
    }
    return 0;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM