算法学习 母函数
母函數(shù)又稱生成函數(shù)。定義是給出序列:a0,a1,a2,.......ak,......,那么函數(shù)G(x)=a0+a1*x+a2*x2+......ak*xk稱為序列a0,a1,a2,.......ak,......的母函數(shù)(即生成函數(shù))。
例如:序列1,2,3.......n的生成函數(shù)為:G(x)=x+2x2+3x3+........nxn。點(diǎn)此鏈接:百度百科
特別的當(dāng)序列為:1,1,1,1,.......1,這個(gè)生成函數(shù)為:G(x)=x+x2+x3+.......+xn=(1-xn)/(1-x),當(dāng)-1<x<1時(shí)G(x)=1/(1-x)
1/(1-x)n=1+C(n,1)x+C(n+1,2)x2+C(n+2,3)x3+...+C(n+k-1,k)xk+...可以把生成函數(shù)還原為數(shù)列。
==========================================================================================================================
例 1:使用母函數(shù)求出斐波那契數(shù)列的通項(xiàng)公式。Fib(n)=Fib(n-1)+Fib(n-2),這里假設(shè)Fib(1)=1,Fib(2)=1;
求解這種遞推關(guān)系的方法是:①、將遞推關(guān)系變成母函數(shù)方程;②、求解母函數(shù)方程;③、將母函數(shù)變成冪級(jí)數(shù)形式。
所以斐波那契數(shù)列的生成函數(shù)為:G(x)=x+x2+2x3+3x4+5x5+8x6..........。
等式兩邊同時(shí)*x有:xG(x)=x2+x3+2x4+3x5+5x6+8x7+.......。
相加有:G(x)+xG(x)=x+2x2+3x3+5x4+8x5+13x6+........。
我們對(duì)比G(x)可以得到:G(x)+xG(x)=G(x)/x-1;所以我們可以得到:G(x)=x/(1-x-x2)。
可以令:1-x-x2=0,得到兩根為:a=(1-√5)/2,b=(1+√5)/2,所以我們可以知道:1-x-x2=(x-x1)(x-x2)=(1-ax)(1-bx);
假設(shè)x/(1-x-x2)=m/(1-ax)+n/(1-bx),通分有:x=m(1-bx)+n(1-ax).由系數(shù)關(guān)系可得m=-1/√5,n=1/√5,所以G(x)=-1/√5(1-bx)+1/√5(1-ax)。
我們可知:1/(1-bx)=1/[1-(1+√5)/2x]是以公比為(1+√5)/2的等比數(shù)列,1/(1-ax)是以公比為(1-√5)/2的等比數(shù)列,所以其通項(xiàng)公式為:Fib(n)=1/√5[bn+1-an+1]。
==========================================================================================================================
例題2:若有1克、2克、3克、4克的砝碼各一 枚,能稱出哪幾種重量?各有幾種可能方案?
構(gòu)造母函數(shù),如果用x的指數(shù)表示稱出的重量,則:
1個(gè)1克的砝碼可以用函數(shù)1+x表示,(前面的這個(gè)1表示1克的砝碼個(gè)數(shù)為0)
1個(gè)2克的砝碼可以用函數(shù)1+x2表示,
1個(gè)3克的砝碼可以用函數(shù)1+x3表示,
1個(gè)4克的砝碼可以用函數(shù)1+x4表示,
那么幾種砝碼的組合情況的用乘積表示有:(1+x)(1+x2)(1+x3)(1+x4)=1+x+x2+2x3+2x4+2x5+2x6+2x7+x8+x9+x10?,系數(shù)即為方案數(shù)。
例稱出重量為6的物品:①、1,2,3;②、2,4兩種方案。
==========================================================================================================================
例題3:求用1分、2分、3分的郵票貼出不同數(shù)值的方案數(shù)?
這個(gè)相對(duì)于上面的那個(gè)例子是:這個(gè)郵票可以重復(fù)。可知其生成函數(shù)為:G(x)=(1+x+x2+....)(1+x2+x4+....)(1+x3+x6+...),同理展開后其系數(shù)即為方案數(shù)。
==========================================================================================================================
例題4:德.梅其里亞克稱重問題
(1)重為a1,a2,a3.....ak的砝碼,如何放在天平的兩端,記可稱重量為n的物體的不同方式為Cn,則Cn的母函數(shù)為:
G(x)=(x-a1+1+xa1)(x-a2+1+xa2).........(x-ak+1+xak) ------?x-a1表示砝碼a1和物體放在同一個(gè)托盤內(nèi),xa1表示砝碼和物體放在不同的托盤內(nèi),1則為不用這個(gè)砝碼。
(2)重為a1,a2,a3....ak的砝碼,如只可以放在天平的一端,記可稱重量為n的物體的不同方式為Cn,則Cn的母函數(shù)為:
G(x)=(1+xa1)(1+xa2).........(1+xak)
==========================================================================================================================
例題5:數(shù)的劃分,將整數(shù)分解為若干個(gè)整數(shù)(相當(dāng)于將n個(gè)蘋果放在n個(gè)無區(qū)別的盤子里,每個(gè)盤子可以放多個(gè),也可以不放),上一篇博文中有提到。
假設(shè)1出現(xiàn)的次數(shù)為記為a1,2出現(xiàn)的次數(shù)記為a2.........k出現(xiàn)的次數(shù)記為ak,那么生成函數(shù)為:
G(x)=(1+x+x2+x3+x4+.....)(1+x2+x4+x6+x8+......)(1+x3+x6+x9+....)........(1+xn)
前面的1+x2+x4+x6+x8+......意思是當(dāng)出現(xiàn)一個(gè)2時(shí)為x2,當(dāng)出現(xiàn)兩個(gè)2時(shí)為x4.....,為什么當(dāng)出現(xiàn)n時(shí),只有兩項(xiàng)(1+xn),因?yàn)槭菍?shù)n劃分為若干項(xiàng),所以不能超過該數(shù),且由數(shù)1到n項(xiàng)數(shù)依次要<=n/k(k=1.2,3,4...n)。
還是以nyist 90(數(shù)的劃分)為例:這里就直接套用網(wǎng)上的模板了
#include<iostream> #include<cstring> #include<algorithm> using namespace std; const int MAX=50; #define CLR(arr,val) memset(arr,val,sizeof(arr)) int n,m,value[MAX],temp[MAX]; int main() { cin>>m; while(m--) { cin>>n; fill(value,value+MAX,1);//value用來存儲(chǔ)系數(shù) CLR(temp,0);//temp用來保存每一次的情況 for(int i=2;i<=n;i++) { for(int j=0;j<=n;j++) for(int k=0;k+j<=n;k+=i) //控制每次系數(shù)的變化和每個(gè)數(shù)出現(xiàn)的最大項(xiàng)數(shù) temp[k+j]+=value[j]; for(int j=0;j<=n;j++) value[j]=temp[j],temp[j]=0; } cout<<value[n]<<endl; } return 0; }?
?例題2:hdu 1085(硬幣問題)
//有3種面額是1、2、5的硬幣,輸入3個(gè)數(shù)字代表每種硬幣的枚數(shù),求最小的不能由這些硬幣組成的面額是多少? #include<iostream> #include<cstring> #include<algorithm> using namespace std; const int MAX=8010; #define CLR(arr,val) memset(arr,val,sizeof(arr)) int value[MAX],temp[MAX],num[3],coin[3]={1,2,5}; int main() { while(cin>>num[0]>>num[1]>>num[2]) { if(num[0]+num[1]+num[2]==0) break; int max=num[0]+2*num[1]+5*num[2]; CLR(value,0); CLR(temp,0); fill(value,value+num[0]+1,1); for(int i=1;i<3;i++) { for(int j=0;j<=max;j++) for(int k=0;k+j<=max&&k/coin[i]<=num[i];k+=coin[i])//注意不能超出個(gè)數(shù) temp[k+j]+=value[j]; for(j=0;j<=max;j++) value[j]=temp[j],temp[j]=0; } for(i=0;i<=max+1;i++)//遍歷即可 if(value[i]==0) {cout<<i<<endl;break;} } return 0; }涉及到母函數(shù)的題目有:HDU 1171,1398,1709,2065,2069,2082,2152;POJ 3046,3716,3734等等~有空再做下
轉(zhuǎn)自https://www.cnblogs.com/13224ACMer/p/4671551.html
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
- 上一篇: SchSvr.exe - SchSvr是
- 下一篇: STL之 set简略介绍。