1. 程式人生 > >母函數及其應用

母函數及其應用

hdu mce tps ima 多少 inf 模擬題 lan main

把離散數列和冪級數一 一對應起來

把離散數列間的相互結合關系對應成為冪級數間的運算關系

最後由冪級數形式來確定離散數列的構造

以上三句話是dalao總結的精髓

然後介紹一下定義:

對於任意數列

技術分享圖片

即用如下方法與一個函數聯系起來:

技術分享圖片

則稱G(x)是數列的生成函數

為了便於理解這個東西,下面給出幾種典型應用:

使用母函數求出斐波那契數列的通項公式

斐波那契數列的生成函數:

G(x)=x+x2+2x3+3x4+5x5+8x6...

等式兩邊同時*x有:

xG(x)=x2+x3+2x4+3x5+5x6+8x7+...

相加有:G(x)+xG(x)=x+2x2+3x3+5x4+8x5+13x6+...

G(x)
+xG(x)=G(x)/x-1 所以我們可以得到:G(x)=x/(1-x-x2) 然後用數學方法可以求得: Fib(n)=1/√5[bn+1-an+1]

若有1克、2克、3克、4克的砝碼各一 枚,能稱出哪幾種重量?各有幾種可能方案?

用x的指數表示稱出的重量

1個1克的砝碼可以用函數1+x表示

(前面的這個1表示1克的砝碼個數為0)

1個2克的砝碼可以用函數1+x^2表示

1個3克的砝碼可以用函數1+x^3表示

1個4克的砝碼可以用函數1+x^4表示

那麽幾種砝碼的組合情況的用乘積表示有

(1+x)(1+x^2)(1+x^3)(1+x^4)

=1+x+x^2+2x^3+2x^4
+2x^5+2x^6+2x^7+x^8+x^9+x^10 系數即為方案數

求用1分、2分、3分的郵票貼出不同數值的方案數?

郵票可以重復

G(x)=(1+x+x^2+....)(1+x^2+x^4+....)(1+x^3+x^6+...)

展開之後的系數就是方案數了

重為a1,a2,a3.....ak的砝碼,如何放在天平的兩端,求可稱重量為n的物體的不同方式

記可稱重量為n的物體的不同方式為Cn

它的母函數為:

G(x)=(x^(-a1)+1+x^a1)(x^(-a2)+1+x^a2).........(x^(-ak)+1+x^ak)

x^(-a1)表示砝碼a1和物體放在同一個托盤內

x
^a1表示砝碼和物體放在不同的托盤內 1則為不用這個砝碼

重為a1,a2,a3....ak的砝碼,如只可以放在天平的一端,求可稱重量為n的物體的不同方式

記可稱重量為n的物體的不同方式為Cn

G(x)=(1+x^a1)(1+x^a2).........(1+x^ak)

數的劃分,將整數分解為若幹個整數

假設1出現的次數為記為a1,2出現的次數記為a2.........k出現的次數記為ak

G(x)=(1+x+x^2+x^3+x^4+.....)
(1+x^2+x^4+x^6+x^8+......)
(1+x^3+x^6+x^9+....)
........
(1+xn)

1+x^2+x^4+x^6+x^8的意思是:

當出現一個2時為x^2,當出現兩個2時為x^4

數的劃分問題在算系數的時候往往結合五邊形數定理,具體見上一篇博文

典型例題是HDU1085,給你cnt1個一元硬幣,cnt2個兩元硬幣,cnt3個五元硬幣,問不能湊出來的第一個面額是多少

公式為

(1+x+x^2+x^3+.........x^cnt1)?(1+x^2+x^4+x^6+.........x^cnt2)?(1+x^5+x^10+x^15+............x^cnt5)

處理完了之後這道題就變成了一道模擬題

 1 #include<cstdio>
 2 #include<cstring>
 3 const int maxn=1e4+5;
 4 int mmax;
 5 int c1[maxn],c2[maxn];
 6 int cnt[5],val[5]={1,2,5};
 7 int main()
 8 {
 9     while(scanf("%d%d%d",&cnt[0],&cnt[1],&cnt[2])==3&&(cnt[0]||cnt[1]||cnt[2]))
10     {
11         memset(c1,0,sizeof(c1));
12         memset(c2,0,sizeof(c2));
13         mmax=0;
14         for(int i=0;i<3;i++)
15             mmax+=cnt[i]*val[i];
16         for(int i=0;i<=cnt[0];i++) c1[i]=1;
17         for(int i=1;i<3;i++)
18         {
19             for(int j=0;j<=mmax;j++)
20             {
21                 if(c1[j]!=0)
22                 {
23                     for(int k=0;k<=val[i]*cnt[i];k+=val[i])
24                     {
25                         if(j+k<=mmax) c2[j+k]+=c1[j];
26                     }
27                 }
28             }
29             memcpy(c1,c2,sizeof(c1));
30             memset(c2,0,sizeof(c2));
31         }
32         int i;
33         for(i=0;i<=mmax;i++)
34             if(c1[i]==0) break;
35         printf("%d\n",i);
36     }
37     return 0;
38 }

母函數及其應用