生成函數(母函數)
法國數學家拉普拉斯(對!就是那個拉普拉斯變換的發明者)在他的著作中提出了生成函數的概念
一、普通生成函數解決組合問題
我認爲生成函數解決組合問題就是把問題轉換成二項式或遞推關係問題的方法
問題
用1元、5元、10元三種紙幣能拼出多少種100元的方案?
這其實是一個組合問題,用三種紙幣組合成100元
這種題用生成函數來做就很方便
下面我們來分析這道題
-
分析1元硬幣的使用情況(五元十元可類比)
一元硬幣在最終的方案中可能用到0次、1次、2次.......
好,接下來,我們嘗試將這個問題轉換成二項式問題
我們將0次寫爲,1次寫爲,2次寫成
則,針對1元硬幣的所有情況就可以表示爲
類比到其他兩種硬幣:
五元硬幣:
十元硬幣:
所以硬幣組合的所有情況就是將以上三個多項式相乘
稍微觀察可知,給出一個 和n,則多項式展開後的項的係數就是組合成n的組合的數量,我們現在想把它化成一個的形式,這樣我們就可以用二項式的係數公式解決問題了。
但是,我們不可能全部打開計算,那就是窮舉了,所以要利用數學知識來解決這個問題
觀察一元硬幣的表達式,明顯是等比數列,則可利用等比數列求和公式得到
我們再來化簡這個式子,我們知道x的取值實際上是沒有意義的,所以爲了化簡,我們規定
所以可得:
類比得:
這個時候我們發現ABC不能化簡成一個二項式的形式,也就是說不能用組合數來表示第N項前面的係數
所以我們轉而求其遞推式
A式不動,仍舊錶示只用1元硬幣的情況,我們來分析一下A中的係數表示
由於得到說明
這是爲什麼呢?由於可以看做將A的每一項指數加1,相減後剩下第一項,後面的項都減沒了,說明n-1項的係數與n項的係數是一樣的即:
接下來用同樣的方法處理,我們用N式表示用1元和5元的情況,D式表示全用的情況即:
我們處理一下上式:
KaTeX parse error: Can't use function '$' in math mode at position 14: N(1-x^5)-A=0 $̲ 打開得 $N-Nx^5-A…
得:
同理可得:
這樣我們就得到了一個遞推關係式:
按照此遞歸關係式可以得到線性時間的算法
代碼:
#include "stdafx.h"
#include <iostream>
int gene5(int n) {
if (n < 5) return 1;
else return gene5(n - 5) + 1;
}
int generation(int n) {
if (n < 5) { return 1; }
else if(n<10)return gene5(n);
else return generation(n - 10) + gene5(n);
}
int main()
{
std::cout<<generation(100);
return 0;
}
二、指數生成函數助攻解決排列問題
我們搞定了組合問題,但是組合問題的解決方法不能解決排列問題,比如說:
拿6個球,有紅球綠球,有多少種方法?
我們來看一下區別,之前錢的問題沒有順序一塊和五塊哪個先挑出來是無所謂的的因素,這次紅綠之間有順序的問題
這樣我們就沒辦法用之前的方法來操作了,這時候,我們用到了拉普拉斯提出的另一種生成函數——指數生成函數
指數生成函數的一般形式是
處理最後得出的生成函數表達式時要化成這樣的基本形式,每項前寫上它的係數(不理解看後面)
我們來看一下與常規生成函數的區別,式子的每一項的指數 n 還是代表選擇 n 個綠(紅)球
如果沒有條件約束,兩個式子乘起來就是綠球和紅球能抽出的所有情況的生成函數
但是跟常規生成函數的區別在於,每一項前面多出了一個常數項
這個數有什麼用呢?
我猜想它跟組合數有關係,你想要把排列的方案數顯示在生成函數中,必須做點什麼,我們來看看它到底做了什麼才能把組合數巧妙地融合進生成函數中
先來看看我們想要什麼,對於某個確定的n(球的總數),當綠球取r個,紅球取n-r個時,我們想要的結果是
明確答案後我們來看一個例子
如果是三個球的組合排列,兩個紅球和三個綠球組成的排列中,對應的項與乘積再化成對應的形式
那麼10就是兩個紅球和三個綠球的方案數,初見很神奇,看一下其中的原理,我們知道:
而和分別是和(n=5,r=2)
他們的乘積可以化成:
分子就是我們要求的方案數。
這時候我們驗證了從數學上來看這個公式的合理性,我們再想一想,它的物理意義究竟是什麼?
最終方案數的多少,可以用組合的和來表示,n!代表了針對一個組合所有排列的合計,而中的用來消除重複的方案數,也就是綠色或紅色自己本身的排序。
##三、生成函數求解任意常係數k階齊次遞推關係
##四、一些例子和總結
…未完