深度解析母函式演算法

2021-09-13 14:00:47 字數 3310 閱讀 8223

在數學中,某個序列 (an)n∈n 的母函式(又稱生成函式,英語:generating function)是一種形式冪級數,其每一項的係數可以提供關於這個序列的資訊。使用母函式解決問題的方法稱為母函式方法。

母函式可分為很多種,包括普通母函式、指數母函式、l級數、貝爾級數和狄利克雷級數。對每個序列都可以寫出以上每個型別的乙個母函式。構造母函式的目的一般是為了解決某個特定的問題,因此選用何種母函式視乎序列本身的特性和問題的型別。

母函式,又稱生成函式,是acm競賽中經常使用的一種解題演算法,常用來解決組合方面的題目。

生成函式的定義:g(x)=a0+a1x+a2x2+a3x3+… 稱g(x) 是序列(a0,a1,a2,a3…)的生成函式;

下面咱們以題目解答的形式,來深入的**普通母函式的原理

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

我們用母函式來解決這個問題

1個1克砝碼可以看成1+x^1,1表示不取,x^1表示取乙個,以下同理

1個2克砝碼可以看成1+x^2

1個3克砝碼可以看成1+x^3

1個4克砝碼可以看成1+x^4

那麼生成函式就是

g(x)=(1+x1)(1+x2)(1+x3)(1+x4)

=1+x+x2+2x3+2x4+2x5+2x6+2x7+x8+x9+x10

這個函式中可以看出重量為3克的方案有兩種,重量為7的方案有兩種,重量為10的有1種。

不難發現指數表示重量,係數表示方案數。

2. 求用1分、2分、3分的郵票貼出不同數值的方案數:大家把這種情況和第一種比較有何區別?第一種每種是乙個,而這裡每種是無限的。

那麼生成函式就是

g(x)=(1+x+x2+x3+…)(1+x2+x4+x6+…)(1+x3+x6+x9+…)

以展開後的x^4為例,其係數為4,即4拆分成1、2、3之和的拆分方案數為4;

即 :4=1+1+1+1=1+1+2=1+3=2+2

//程式設計解決

/*author: 熊謙智

題目描述:母函式模板

涉及演算法:這種母函式是表示從每一類中每次能拿乙個價值是a[i]的元素 可以拿無限多個

*/#include#includeusing namespace std;

const int n = 105, m = 1e6+5;

int dp[m], temp[m];

int main()

sort(a,a+n);

// 先用第一種 (最小的一種)初始化 dp陣列 -- 對應母函式的第乙個括號

for (int i = 0; i < target; i+=a[0])

for (int i = 1; i < n; i++)

}for (int j = 0; j <= target; j++)

}cout << dp[target] << endl;

}}

①  、首先對dp初始化,由第乙個表示式(1+x+x^2+..x^n)初始化,把質量從0到n的所有砝碼都初始化為1.

② 、 i從2到n遍歷,這裡i就是指第i個表示式,上面給出的第二種母函式關係式裡,每乙個括號括起來的就是乙個表示式。

③、j 從0到n遍歷,這裡j就是(前面i個表示式累乘的表示式)裡第j個變數,如(1+x)(1+x^2)(1+x^3),j先指示的是1和x的係數,i=2執行完之後變為

(1+x+x^2+x^3)(1+x^3),這時候j應該指示的是合併後的第乙個括號的四個變數的係數。

④ 、 k表示的是第j個指數,所以k每次增i(因為第i個表示式的增量是i)。

⑤ 、把temp的值賦給dp,而把temp初始化為0,因為temp每次是從乙個表示式中開始的。

例題 :

可以搜藍橋杯 包子湊數 這題既可以用完全揹包 也可以用母函式來解答

nyoj -90-數的劃分

hdu 1085(硬幣問題)

nyoj-588-money

在網上你總能看到該題的不同**實現,例如
// 之所以可以用下面的**實現是因為題目中給出的就是 a[i] = i

// 而當a[i] != i 就不能用下面的**實現

#include using namespace std;

const int _max = 10001;

// c1是儲存各項質量砝碼可以組合的數目

// c2是中間量,儲存每一次的情況

int c1[_max], c2[_max];

int main()

for(i=2; i<=nnum; ++i) // ----- ②

for(j=0; j<=nnum; ++j) // ---- ⑤

} cout << c1[nnum] << endl;

} return 0;

}

3. 設有n個標誌為1,2,…,n的網袋,第i個(i=1,2,…n)網袋裡放有ni個球。不同網袋裡的球是不同的,而同一網袋裡的球則是沒有差別的,認為是相同的。詢問從中取r個球的方案數。

設生成函式

第幾個大括號表示是第幾個袋子 x 的指數表示從中取多少個球

g(x)=(1+x1+x2+…+xn1)(1+x1+x2+…+xn2)…

最後指數為r的那一項的係數就是方案數。

/*

author: 熊謙智

題目描述:

涉及演算法:這種母函式是表示從每一類中可以抽取 1-a[i] 個

*/#include#includeusing namespace std;

const int n = 105, m = 1e6+5;

int dp[m], temp[m];

int main()

sort(a,a+n);

// 先用第一種 (最小的一種)初始化 dp陣列 -- 對應母函式的第乙個括號

for (int i = 0; i <= a[0] && i <= target; i++)

for (int i = 1; i < n; i++)

}for (int j = 0; j <= target; j++)

}cout << dp[target] << endl;

}} /*// 表示有3個網袋 從中選取10個求 共有多少總不同的方法

3 10

4 2 9

*/

總結一下,生成函式大多用來解決有限或無限物體的組合方案。

演算法學習 母函式

母函式又稱生成函式。定義是給出序列 a0,a1,a2,ak,那麼函式g x a0 a1 x a2 x2 ak xk稱為序列a0,a1,a2,ak,的母函式 即生成函式 特別的當序列為 1,1,1,1,1,這個生成函式為 g x x x2 x3 xn 1 xn 1 x 當 11 1 x n 1 c n...

KMP演算法深度解析

摘要 kmp演算法是字串匹配的經典演算法,由於其o m n 的時間複雜度,至今仍被廣泛應用。大道至簡,kmp演算法非常簡潔,然而,其內部卻蘊含著玄妙的理論,以至許多人知其然而不知其所以然。本文旨在解開kmp演算法的內部玄妙所在,希望能夠有助於學習與理解。1 kmp演算法 一種改進的字串匹配演算法,由...

ftok 函式深度解析

關於ftok函式,先不去了解它的作用來先說說為什麼要用它,共享記憶體,訊息佇列,訊號量它們三個都是找乙個中間介質,來進行通訊的,這種介質多的是。就是怎麼區分出來,就像唯一乙個身份證來區分人一樣。你隨便來乙個就行,就是因為這。只要唯一就行,就想起來了檔案的裝置編號和節點,它是唯一的,但是直接用它來作識...