第一次當標題黨真是有點不適應php
如今網上講生成函數的教程大多都是從\(\frac{1}{1-x} = \sum_{i=0}^{\infty}x^i, e^x = \sum_{i=0}^{\infty} \frac{x^i}{i!}\)開始,可是我不認爲這樣有助於你們理解生成函數的本質。我最開始學的時候也是在這裏蒙了很久,直到看到了朱全民老師的課件,才真正的理解了生成函數的本質——處理排列組合問題的有利工具,而不是簡單的\(\frac{1}{1-x}\)的指標代換。因此這篇文章,我打算從最基本的排列組合問題寫起,最後慢慢擴展到\(\frac{1}{1-x} = \sum_{i=0}^{\infty}x^i, e^x = \sum_{i=0}^{\infty} \frac{x^i}{i!}\)。內容會比較基礎,高端玩家能夠直接看鏼爺的集訓隊論文html
維基百科上是這麼定義的:函數
在數學中,某個序列\((a_n)_{n \in \mathbb{N}}\) 的母函數(又稱生成函數,英語:Generating function)是一種形式冪級數,其每一項的係數能夠提供關於這個序列的信息。工具
講的通俗一點,對於某個序列\({a_0, a_1, \dots, a_n}\),我想找一個函數來表示它,假設是\(G(x) = a_0 + a_1x + a_2x^2 \dots a_n x^n\)。這時候函數第\(i\)項的係數就表示了序列中的第\(i\)個元素。同時咱們也能夠看到,函數中的自變量\(x\)好像並無什麼意義,他的取值並不影響序列的表示,所以咱們稱這種函數爲形式冪級數學習
那麼這樣定義由什麼好處呢?spa
咱們仔細觀察一下\(G(x)\),不難發現這是一個多項式函數,對於多項式咱們知道他有加、減、乘、除、求逆、取ln、exp等運算。那麼咱們對\(G(x)\)進行乘法運算,也就是至關於對序列進行乘法運算,那麼這樣幹有什麼意義呢?咱們不妨從一個題目入手。code
有三種物品,分別有\(3, 2, 3\)個,問拿出\(4\)個進行組合\((\{1123\}, \{3211\}\)算一種)的方案數是多少htm
學過dp的人可能會一眼看出是揹包板子題。直接設\(f[i][j]\)表示當前到第\(i\)個位置,已經選了\(j\)個物品的方案數。轉移的時候枚舉一下當前選了幾個blog
f[0][0] = 1; for(int i = 1; i <= 3; i++) for(int j = 0; j <= 8; j++) //當前總共要選出j個 for(int k = 0; k <= j; k++) //已經選了k個 if(j - k <= v[i]) //此時要選j-k個 f[i][j] += f[i - 1][k];
能夠獲得\(f[3]\)的係數爲\(\{1\ 3\ 6\ 9\ 10\ 9\ 6\ 3\ 1 \}\)(從0開始編號),\(4\)最對應的一項是\(10\)。教程
那用生成函數怎麼作呢?
咱們能夠對每一個物品構造一個多項式函數,其中第\(i\)項的係數\(a_i\)表示選了\(i\)個當前物品的方案數。
那麼第一個物品的生成函數爲\(G_1(x) = 1 + x^1 + x^2 + x^3\) (相同的物品選\(i\)個的方案數固然是1)
第二個物品的生成函數爲\(G_2(x) = 1 + x^1 + x^2\)
第三個爲\(G_3(x) = 1 + x^1 + x^2 + x^3\)
先說結論:最終答案是\(G_1(x) * G_2(x) * G_3(x)\)的第\(4\)項的係數
這是爲何呢?考慮兩個多項式相乘的結果\(f* g\),它的第\(k\)項的係數爲\(\sum_{i=0}^k f_i g_{k-i}\)。這個過程是至關因而在枚舉第一個物品選了幾個,好比\(4\)這一項,他等於\(f_0g_4 + f_1g_3 + f_2 g_2 + f_3g_1 + f_4g_0\)。
再具體一點,拋開剛剛那個題目中係數等於\(1\)的限制,咱們假設\(f_1 = 2, g_3 = 3\),也就是說從第一個物品中選出\(1\)個有兩種方案,第二個物品中選出\(3\)個有三種方案,那麼\(f_1 * g_3=2 * 3\)就至關於第一個物品的兩種方案能夠與第二個物品的三種方案任意組合來獲得\(4\)種物品。(再看不懂的話建議去補一下高中組合計數qwq,這裏講的這麼詳細是爲了給指數生成函數作鋪墊)
這裏建議你們去手玩一下多項式乘法,玩一下(玩的時候枚舉\(x^i\)算他的係數)就會發現這個過程與揹包的過程驚人的類似,由於事實上揹包的過程就是在模擬多項式乘法。
這裏爲了下文(指數型生成函數)好講解,本菜雞直接把多項式相乘的結果(抄一下)寫出來
\[ \begin{aligned} G(x) &= (1+x+x^2+x^3)(1+x+x^2)(1+x+x^2+x^3) \\ &= (1+2x+3x^2+3x^3+2x^4+x^5)(1+x+x^2+x^3)\\ &=1+3x+6x^2+9x^3+10x^4+9x^5+6x^6+3x^7+x^8 \end{aligned} \]
其中\(x^4\)項能夠由下面這些獲得,這種形式與咱們的手玩結果就很是類似了
\[x_1x_3^3+x_2x_3^3+x_1^2x_3^2+x_1x_2x_3^2+x_2^2x_3^2+x_1^3x_3+x_1^2x_2x_3+x_1x_2^2x_3+x_1^3x_3+x_1^2x_2^2\]
形如\(G(x) = \sum_{i=0}^n a_ix_i\)的表示一個序列的多項式函數,咱們稱之爲普通生成函數
講到這裏你須要大概明白:生成函數的基本概念,生成函數相乘的組合意義。
接下來按道理應該講\(\frac{1}{1-x}\)及其運算,可是我想先介紹一下指數生成函數的基本概念。
經過剛剛的講解咱們不難看出,普通生成函數的意義在於解決組合類計數問題。可是別忘了組合的兄弟排列呀。指數生成函數就是用來解決排列類問題。
仍是剛剛的題目,咱們改一下限制
有三種物品,分別有\(3, 2, 3\)個,問拿出\(4\)個進行排列\((\{1123\}, \{3211\}\)算不一樣方案)的方案數是多少(HDU1521)
這一類問題僅僅是比剛剛多了一個順序的緣由,可是難度卻比剛剛大了很多(揹包也能夠作,只要在轉移的時候乘一個組合數便可,留給你們思考)
這裏先介紹一下多重集排列數
設\(S = \{a_1, a_2 \dots a_n\}, N = \sum_{i=1}^n a_i\),其中第\(a_i\)表示第\(i\)個物品有\(a_i\)個。
從中選出\(N\)個進行排列的方案數爲\(\frac{N!}{a_1!a_2! \dots a_n!}\)
解釋的話就是至關於任意排列以後減去同種物品之間多出來的方案
這樣咱們就獲得了一個思路:先把全部組合獲得的方案算出來,而後再對每一種方案分別計算排列數,最後加起來。
好比咱們剛剛已經獲得了組合的方案:
\[x_1x_3^3+x_2x_3^3+x_1^2x_3^2+x_1x_2x_3^2+x_2^2x_3^2+x_1^3x_3+x_1^2x_2x_3+x_1x_2^2x_3+x_1^3x_3+x_1^2x_2^2\]
其中\(x_1 x_3^3\)這一項的排列方案就是\(\frac{4!}{1!3!}\),\(x_1x_2x_3^2\)這一項的排列方案就是\(\frac{4!}{1!1!2!}\)。觀察一下,全部方案的分子都是\(4!\),分母都是選出來的對應數量的階乘。
因而咱們引進指數型生成函數
形如\(G(x) = \sum_{i=0}^n a_i \frac{x_i}{i!}\)的表示序列的多項式函數,咱們稱之爲指數生成函數。
同時咱們分別構造出\(G_1(x) = 1+\frac{x^1}{1} + \frac{x^2}{2!} + \frac{x^3}{3!}\)
\(G_2(x) = 1 + \frac{x^1}{1} + \frac{x^2}{2}\)
\(G_3(x) = 1 + \frac{x^1}{1} + \frac{x^2}{2!} + \frac{x^3}{3!}\)
這時候再計算一下\(G_1(x) * G_2(x) * G_3(x)\)
\[ \begin{aligned} G_e(x) &= (1 + \frac{x}{1!} + \frac{x^2}{2!} + \frac{x^3}{3!})(1+\frac{x}{1!} + \frac{x^2}{2!}) (1 + \frac{x}{1!} + \frac{x^2}{2!} + \frac{x^3}{3!})\\ &= (1+2x+2x^2+\frac{7}{6}x^3 + \frac{5}{12}x^4 + \frac{1}{12}x^5) (1+x+\frac{1}{2}x^2 + \frac{1}{6}x^3)\\ &=(1+3x + \frac{9}{2}x^2 + \frac{14}{3}x^3 + \frac{35}{12}x^4 + \frac{17}{12}x^5 + \frac{35}{72} x^6 + \frac{8}{72}x^7 + \frac{1}{71}x^8) \end{aligned} \]
這時候如何計算選出\(4\)個物品的答案呢?簡單\(\frac{35}{12} * 4! = 70\)
可能你們不由思考,爲何這麼定義函數乘起來就是排列數呢?想想,由於咱們對每一個係數構造的\(\frac{1}{i!}\)就至關因而多重集排列數中的分母呀
好了,若是你到這裏都看懂了的話,說明你已經對生成函數有個大概的瞭解了。可是不知道你們是否是和我有着一樣的感受:生成函數好麻煩啊qwq。
那麼有沒有一套能夠簡化些運算的理論呢?
答案是:固然有了!(否則我問個毛線)。下面講的內容能夠會有些刺激,須要你們有必定的數學基礎(其實只要高中知識就好了)
這個也不能叫推廣吧,是我本身瞎起的名字。。。
在咱們剛剛的運算中出現了一個經常使用的函數\(G(x) = \sum_{i=0}^n x^i\),這個東西怎麼化簡呢?
結論:\(\sum_{i=0}^{\infty} x^i = \frac{1}{1-x}\)
可能你和當初一次見到這個式子的我同樣,大概是這個表情
咱們來證實一下。
\(S = 1 + x + x^2 + \dots x^{\infty}\)
\(xS = x + x^2 + x^3 + \dots x^{\infty}\)
\(S - xS = 1\)
\(S = \frac{1}{1-x}\)
是否是證的完美無缺可是又十分扯淡?由於這玩意兒顯然只有\(x^{\infty}\)收斂也就是\(x\in(-1, 1)\)時成立。其實在這裏只要在\(x\in(-1, 1)\)成立就能夠了,由於生成函數是形式冪級數,咱們並不關心\(x\)的具體取值
有了這個咱們能幹什麼呢?咱們能夠對\(\frac{1}{1-x}\)變形來表示更多的序列,同時咱們知道了\(\frac{1}{1-x}\)對應序列的第\(i\)項的係數爲\(1\),那麼當咱們知道了某一個序列的生成函數以後咱們也能夠把它變成相似於\(\frac{1}{1-x}\)的形式從而獲得通項公式。
首先介紹一些簡單的變換,建議你們手玩一下下面的生成函數的推廣形式,好比把"乘\(2\)"換成"乘\(k\)"
將\(x\)替換爲\(-x\),\(\frac{1}{1+x} = {1, -1, 1, -1, \dots}\)
將\(x\)替換爲\(2x\),\(\ \frac{1}{1-2x} = {1, 2, 4, 8, 16, \dots}\)
將\(x\)替換爲\(x^2\), \(\ \ \ \frac{1}{1-x^2} = {1, 0, 1, 0, 1 \dots}\)
將分子乘\(2\), \(\ \ \ \ \quad\frac{2}{1-x} = {2, 2, 2, 2, 2, \dots}\)
將分子乘\(x^3\), \(\ \ \quad \frac{x^3}{1-x} \ = {0, 0, 0, 1, 1, 1, 1 \dots}\)
求個導, \(\qquad \ \ \ \ \ \frac{1}{(1-x)^2} = {1, 2, 3, 4, 5} \dots\)
再求一次, \(\quad \ \ \ \frac{2}{(1-x)^3} ={2 + 6 + 12 + 20 \dots}\)
問題來了,我若是知道了某一個數列的生成函數,怎麼求它的通項公式呢?通常的思路就經過各類奇技淫巧往上面的幾個生成函數轉化。這裏要提一下比較經常使用的廣義二項式定理
\[\frac{1}{(1-x)^n} = \sum_{k=0}^{\infty} C_{n+k-1}^{k-1} x^k\]
咱們來經過兩個例子來具體講一下它的用處
很是不不要臉的抄一下本身之前的博客
首先要知道斐波那契數列的遞推式
\[f_i = f_{i-1} + f_{i - 2}\]
\[f_0 = f_1 = 1\]
那麼推導一下
設\(A = 1 + 1x + 2x^2 + 3x^3 + 5x^4 + 8x^5 \dots\)
根據遞推式,咱們能夠這樣變化,顯然有
\[ \begin{aligned} A = \ 1 + 1x + &2x^2 + 3x^3 + 5x^4 + 8x^5 \dots \\ xA = \ \ \qquad x + &1x^2 + 2x^3 + 3x^4 + 5x^5\dots \\ x^2A =\qquad \qquad &1x^2 + 1x^3 + 2x^4 + 3x^5 \dots \end{aligned} \]
那麼能夠獲得一個方程\(A - xA - x^2A = 1\)
整理一下\(A =\frac{1}{1-x-x^2}\)
這樣咱們就獲得了斐波那契數列的生成函數,然而並無什麼卵用,由於咱們不能直接經過觀察看出每一項的係數。
如今考慮一下,咱們接下來能夠幹什麼。咱們已經知道了\(\frac{1}{1-x}\)和\(\frac{1}{1-kx}\)所表示的序列。接下來要乾的固然是把\(\frac{1}{1-x-x^2}\)往上面的兩個式子轉化。
\(\frac{1}{1-x-x^2}\)這玩意兒下半部分是個一元二次方程,咱們能夠配方
\[1-x-x^2 = (1-\phi_1x)(1-\phi_2x)\]
\[\phi_1 = \frac{1+\sqrt{5}}{2}, \phi_2 = \frac{1-\sqrt{5}}{2}\]
(解的時候能夠直接把後面的式子拆開,把這兩個式子對應項聯立組成方程組, \(\phi_1 \phi_2\)的取值是能夠反過來的)
這個時候咱們發現已經找到與\(\frac{1}{1-kx}\)的聯繫了,咱們能夠把\(\frac{1}{(1-\phi_1 x)(1-\phi_2 x)}\)拆成求和的形式。能夠裂一下項
原式變爲\(\frac{a}{1-\phi_1x} + \frac{b}{1-\phi_2 x}\),而後再解一個方程\(a(1-\phi_2 x) + b(1-\phi_1x) = 1\)
解這個方程就沒那麼休閒了,這裏咱們選擇把\(x\)當作主元對方程進行變換
\[(a+b - 1) - x(a\phi_2 + b\phi_1) = 0 \]
這樣就好處理了,只要列個二元一次方程組
\[ \begin{cases} a+b-1 = 0\\ a\phi_2 + b\phi_1 = 0 \end{cases} \]
解一下能夠獲得\(a = \frac{1}{\sqrt{5}} \phi_1, b = -\frac{1}{\sqrt{5}} \phi_2\)
帶回去
\[A = \frac{\phi_1}{\sqrt{5}} \frac{1}{1-\phi_1x} - \frac{\phi_2}{\sqrt{5}} \frac{1}{1-\phi_2x}\]
那麼第\(n\)項的公式爲
\[A_n = \frac{1}{\sqrt{5}} ((\frac{1+\sqrt{5}}{2})^{n+1} - (\frac{1-\sqrt{5}}{2})^{n+1})\]
好比這種休閒板子題
至多爲\(k\)就是\(\frac{1-x^{k+1}}{1-x}\)
\(k\)的倍數就是\(\frac{1}{1-x^k}\)
化簡完了就只剩下一個\(\frac{1}{(1-x)^5}\)
這個東西能夠直接廣義二項式定理展開,而後交一發pypy2就過了。。
和上面的很相似,這裏直接說結論
\[e^x = \sum_{i=0}^{\infty} \frac{x^i}{i!}\]
證實
考慮直接將\(e^x\)在\(x_0 = 0\)處泰勒展開
由泰勒展開的公式\(f(x) = f(x_0) + \frac{f^1(x_0)}{1} (x-x_0) + \frac{f^2(x_0)}{2!} (x-x_0)^2 + \dots + \frac{f^n(x0)}{n} (x-x_0)^n \xi\) (\(f^n\)的意思是求\(n\)次導數)
能夠直接獲得。
一些經常使用變換
\(e^{-x} = 1 - \frac{x}{1} + \frac{x}{2!} -\frac{x}{3!} + \frac{x}{4!}\dots\)
\(\frac{e^x + e^{-x}}{2} = 1 + \frac{x^2}{2!} + \frac{x^4}{4!} + \frac{x^6}{6!}\dots\)
\(\frac{e^x - e^{-x}}{2} = \frac{x}{1} + \frac{x^3}{3!} + \frac{x^5}{5!} + \frac{x^7}{7!}\)
\(e^{kx} = 1 + \frac{kx}{1} + \frac{k^2x^2}{2!} + \frac{k^3x^3}{3!} + \frac{k^4x^4}{4!} \dots\)
長度爲\(n\)的序列,用紅黃藍綠四種顏色染色,其中紅黃只能是偶數,問方案數
\(n \leqslant 10^9\)
這道題就比較休閒了
任意的是\(e^x\),偶數的是\(\frac{e^x + e^{-x}}{2}\)
最後化完是\(\frac{e^{4x} + 2e^{2x}+1}{4} = \frac{4^n+2 * 2^{n+1}}{4}\)(\(\frac{1}{4}\))至關於常數項
直接快速冪就能夠求
本篇講的是關於生成函數最基礎的內容,千萬不要認爲本身看懂了上面的內容就會生成函數了,充其量也就是了解而已。生成函數理論十分博大精深,我也只是略知皮毛。過幾天可能會根據學習狀況更一些生成函數與多項式運算的東西,敬請期待吧qwq