普通母函数:
在用到母函数之前啊,恐怕很少有人听过母函数,我也一样,我当时是做杭电acm的2082题要用母函数做才去了解母函数的。当然母函数分为很多种,包括普通母函数、指数母函数、L级数、贝尔级数和狄利克雷级数,我这里说的都是普通母函数。
什么是普通母函数呢,——把组合问题的加法法则和幂级数的的乘幂的相加对应起来,这句话可能一开始难以理解,不过其实学完了之后很容易理解,母函数的思想很简单—就是把离散数列和幂级数一一对应起来,把离散数列间的相互结合关系对应成为幂级数间的运算关系,最后由幂级数形式来确定离散数列的构造。
我就从那个经典的砝码的例子讲起。
题目:有1克、2克、3克、4克的砝码各一 枚,能称出哪几种重量?每种重量各有几种可能方案?
穷举的话很容易就可以得出结果,但是很显然这种类型的穷举需要花费的时间是n4方级别,计算机还可以在比较短的而时间内算出来,但是如果给出m种砝码,那么就是nm次方级别,那么如果砝码种类一多,计算机恐怕就无法在短时间内给出答案。而通过用母函数可以把这类题的时间规模压缩到n3级别,使得计算机能很快给出解答。
我们先来看看穷举的过程,先假设使用一个1g的砝码,然后再假设在此情况下,使用2g的砝码,在此基础上,再假设使用一个3g的,再假设使用一个4g的,这就是1中情况,显然,这种方案称出的重量为10g,然后改变上面的一个假设条件,比如假设没有使用4g的,只是用了1g、2g、3g,显然这种方案称出的是6g,以此类推,将所有的可能列举出来后即可得到全部的方案,1g的砝码有两种情况,使用还是不使用,其他的砝码也一样,每一种1g砝码的状态都可以有两种砝码状态,以此类推总共就有2*2*2*2=16中方案,当然其中包含一种一个砝码也没有的0g方案。
我们最后可以穷举出结果:1g、2g、8g、9g、10g各有一种方案,3g、4g、5g、6g、7g各有两种,总共十五种,这是在不算一种0g的方案的时候,算上就是16种,和上面的过程相符。
我们可以用一个类似离散数学的逻辑式表示前两种砝码组合出来的情况
我在这里使用||表示析取,也就是编程时的“逻辑或”;用&&表示合取,也就是编程时的“逻辑与”,析取与合取都是离散数学中的概念,其实就等于编程语言中的逻辑与和逻辑或,析取与合取的符号ˆ和ˇ很多人虽学过并不熟悉,我就用编程语言中的符号代替了,熟悉离散数学的人可以转换成析取与合取的符号。
(使用1g || 不使用1g)&&(使用2g || 不使用2g)
=使用1g&&使用2g || 不使用1g&&使用2g || 使用1g&&不使用2g || 不使用1g&&不使用2g
每个用 “||”分开的一项都是一种方案。“&&”表示选择第一项的情况下有选择了第二项。
大家可以发现这个表达式和一种表达式很像,没错,如果把“||”看成加法,“&&”看成乘法,和多项式的乘法一模一样。那么我们直觉的想到,有没有可能用多项式乘法来表示组合的情况呢?我们再来看题目,题目需要的是几种砝码组合后的重量,是一个加法关系,但是在上式中“&&”是一种类似于乘法的运算关系,这怎么办呢?有没有什么这样一种运算关系,以乘法的形式运算,但是结果表现出类似于加法的关系呢?正好有一个,那就是幂运算。Xm 乘上Xn结果是Xm+n,他完美的符合了我们的要求。那么以次数表示砝码的质量, 就可以以多项式的形式表示砝码组合的所有方案。
还是以前两个砝码为例说明,表示1g砝码的两种状态的多项式就是(x0+x1),表示2g的就是(x0+x2),x0表示没有使用砝码,所以重量为0,当然了因为x0 =1,所以也可以写成1,后面为了方便我会这么写。注意,砝码的质量是以次数表示的,而不是直觉上的用下标表示为x1,x2。这点很重要,不然的话就无法表现出幂运算的关系了。
(x0+x1)*(x0+x2)
=x0*x0 + x1*x0 + x0*x2 + x1*x2
=x0 + x1 + x2 + x3
很显然,有四种方案,0g、1g、2g、3g,结果与我们穷举的结果相同,而如果结果中有相同的项,那么合并同类项后每一项的系数就是这种重量有几种实现方案,这会在我们用此方法解决4个砝码问题的时候得到证明。
那么接