母函数GeneratingFunction

Posted Chivas_/Regal

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了母函数GeneratingFunction相关的知识,希望对你有一定的参考价值。

思考问题:
如果有10种不同颜色的球各一个,从中取两个,不同的取球方案是多少?
简单的排列组合问题,很轻松就能 C 10 2 C_{10}^2 C102 = 45
但如果换一种问题,有面值1、2、3、4、5、…、99、100元的硬币各一枚,那么有多少种组成方案?

😄普通型母函数

📕前置芝士

🎈幂相乘

幂次相乘 = 指数相加
x a ∗ x b = x a + b x^{a} * x^{b} = x^{a + b} xaxb=xa+b

🎈Hash

将某个数存入某个地址内从而完成某种映射关系,并可以 O ( 1 ) O(1) O(1)的时间内查找到和进行操作
母函数算法某种程度上利用了hash的,了解hash可以更深刻地理解该算法
Hash传送门

📕概述

🎈概念 & 用处

母函数分为普通型母函数与指数型母函数
普通型母函数用于解决多重集的组合问题
指数型母函数用于解决多重集的排列问题

在某种意义上可以联系起来背包问题进行思考
两者有互通之处但同时又能解决两种不同的问题

我们定义一个序列 a 0 、 a 1 、 a 2 、 . . . a_0、a_1、a_2、... a0a1a2...并构造一函数
G x = a 0 + a 1 x + a 2 x 2 + . . . G_x = a_0 + a_1x + a_2x^2 + ... Gx=a0+a1x+a2x2+...
则称 G x G_x Gx是序列 a 0 、 a 1 、 a 2 、 . . . a_0、a_1、a_2、... a0a1a2...的母函数

同时如果已知函数 G x = ( 1 + x ) 2 G_x = (1 + x)^2 Gx=(1+x)2
则在展开后可以得到 G x = 1 + 2 x + x 2 G_x = 1 + 2x + x^2 Gx=1+2x+x2
则有该函数是序列 1 、 2 、 1 1、2、1 121的母函数

🎈构造表示

例如我们规定:有1元硬币,3元硬币,5元硬币,问都可以构造出来什么数值
我们利用以下规则:
每一种硬币都为一个小括号内的多项式
同时将硬币面值x作为指数(从0开始,x1,x2,…)

在这里我们构建1元硬币的多项式: 1 + x + x 2 + x 3 + x 4 + x 5 + . . . 1 + x + x^2 + x^3 + x^4 + x^5 + ... 1+x+x2+x3+x4+x5+...
我们能很轻松发现1元硬币能构造出的数值为0、1、2、3、4、5、…
构建3元硬币的多项式: 1 + x 3 + x 6 + x 9 + . . . 1 + x^3 + x^6 + x^9 + ... 1+x3+x6+x9+...
我们可以发现3元硬币构造出的数值为0、3、6、…
构建五元硬币的多项式: 1 + x 5 + x 10 + . . . . 1 + x^5 + x^{10} + .... 1+x5+x10+....
得到数值0、5、10、…

在得到所有硬币能构造出来的数值时,我们利用这几个多项式相乘
( 1 + x + x 2 + x 3 + x 4 + x 5 + . . . ) ∗ ( 1 + x 3 + x 6 + x 9 + . . . ) ∗ ( 1 + x 5 + x 10 + . . . . ) = 1 + x 1 + x 2 + 2 x 3 + 2 x 4 + 3 x 5 + 4 x 6 + 4 x 7 + 5 x 8 + 6 x 9 + 7 x 10 + . . . . . (1 + x + x^2 + x^3 + x^4 + x^5 + ...) * (1 + x^3 + x^6 + x^9 + ...) * (1 + x^5 + x^{10} + ....) = 1 + x^1 + x^2 + 2x^3 + 2x^4 + 3x^5 + 4x^6 + 4x^7 + 5x^8 + 6x^9 + 7x^{10} + ..... (1+x+x2+x3+x4+x5+...)(1+x3+x6+x9+...)(1+x5+x10+....)=1+x1+x2+2x3+2x4+3x5+4x6+4x7+5x8+6x9+7x10+.....
b x a bx^a bxa表示有b种不同的方法能构造出来数值a
其中每一种情况都能有对应的结果,但同时不同的情况构造出来同样的数值时,这两种情况又会累加,所以我们可以得到都能构建出什么数值,与构建出来某种数值有几种方法

🎈过程

建立两个数组c1,c2,c1i表示前面括号合并后指数i的系数,c2i表示下一个准备合并的括号的指数i的系数
1.初始化第一个多项式
2.多项式两两合并(括号的合并){
    数值映射累加给c2,c2[第一个括号某个指数 + 第二个括号某个指数] += c1[第一个括号某个指数]
    c2的值赋给c1,c2清空
}

📕程序实现

const int maxn=10000;
int c1[maxn + 1];//c1[i]表示母函数第一个小括号内的表达式中,指数为i的系数
int c2[maxn + 1];//第二个的系数(职业备胎(狗头))
int main(){
    int n;//组合出来n
    while(cin >> n)
    {
        memset(c1, 0, sizeof(c1));
        memset(c2, 0, sizeof(c2));
        for(int i = 0; i <= n; i += elem[1]) c1[i] = 1;//对第一个括号的内容进行赋1
        
        //=========================================主体
        for(int i = 2; i <= n; i ++)//做n-1趟前两括号合并
        {
            for(int j = 0; j <= n; j ++)//第1个括号
            {
                for(int k = 0; k + j <= n; k += elem[i])//第2个括号,(k+=i)是因为下一个括号指数会+=i
                     c2[j + k] += c1[j];//合并后系数相加,要继承一下上一个
            }
            for(int j = 0; j <= n; j ++)//替换一下第一个括号数组,初始化下一个括号数组
            {
                c1[j] = c2[j];
                c2[j] = 0;
            }
        }
        //=============================================
        cout << c1[n] << endl;//此时就剩一个括号,c1[n]即为合并结束后的n次方系数
    }
}

😄指数型母函数

思考:
考虑n个元素组成的多重集,其中a[1]重复了n[1]次,a[2]重复了n[2]次,…,a[k]重复了n[k]次,n = n[1] + n[2] + … + n[k]。
现在从中取r个进行排列,求不同的排列数
解:若r = n,即考虑n个元素的全排列,则

以上是关于母函数GeneratingFunction的主要内容,如果未能解决你的问题,请参考以下文章

母函数 入门 + 模板

生成函数(母函数)入门详解

母函数入门+模板(转)

概率论中的矩母函数(MGF)

HDU 2082 母函数模板题

2189 ACM 母函数 素数