Open guevara opened 1 week ago
The Mother Function - spirits away https://ift.tt/0paKevk
生成函数(mother function)是一种非常诡异的求数列通项的方法。核心思想是把数列a的第n项当作某个某个位置函数A(x)的xn系数系数。我们通过递推式来求得A(x),然后将A(x)展开来得到xn的系数既是数列的通项:
下面我们就以几个循序渐进的例子来讲解这个生成函数方法的使用。
线性递推式是数列递推式中最简单的递推式,其形式如下:
其中p,q为常数。这里为了简单起见,我们以p=2,q=1,a0=0为例来说明生成函数方法的使用。假设该数列的生成函数为A(x)=∑i=0aixi,则我们可以得到
(3)A(x)=∑i=0aixi=a0+∑i=0ai+1xi+1=a0+∑i=0(2∗ai+1)xi+1=a0+x∗(2∗∑i=0aixi+∑i=0xi)=a0+x∗(2∗A(x)+∑i=0xi)=a0+2x∗A(x)+x1−x=2x∗A(x)+x1−x
由此我们可以得到:
(4)A(x)=x(1−x)(1−2x)=x{21−2x−11−x}={2x+(2x)2+(2x)3+⋯}−{x+x2+x3+⋯}=∑i=1(2i−1)xi
所以,通过这么长的递推,我们终于得到了ai=2i−1,虽然说这个递推高一水平的人就可以做出来。但是我们总是会经历一个从这TM也需要证到这TM也能证的过程吧。
所谓伪线性递推是我生造的一个词,其递推结构与之前的一样,只不过q,p可能为i的线性表示。下面以例子来说明:
这里重复之前的推导过程,我们可以得到:
(6)A(x)−1=2x∗A(x)+x∑i=1ixi
此时我们需要利用微积分的知识:
(7)∑i=1ixi=∑i=1x(d(xn)dx)=x(ddx)∑i=1xi=x(ddx)11−x)=x(1−x)2
所以,我们将上式带入到之前,可以得到:
(8)A(x)=1−2x+2x2(1−x)2(1−2x)=−1(1−x)2+21−2x
又因为
所以
斐波那契数列作为数列里面最经典的例子,本文自然不能放过。其数列递推式如下:
(11)Fn+2=Fn+1+Fnw.r.t.F0=0,F1=1
同样 ,设其生成函数为A(x) ,我们可以得到
(12)A(x)=x+x(F2x+F3x2+F4x3+⋯)=x+x{{F1x+F2x2+F3x3+⋯}+{F0x+F1x2+F2x3+⋯}}=x+x(A(x)+xA(x))
(13)A(x)=x1−x−x2=15{1(1−(1+5)x/2−11−(1−5)x/2}
然后经过一些稀里糊涂的中间步骤,我们可以得到
(14)Fi=15((1+52)i−(1+52)i)
在上文中我们只涉及到了一个变量x,此时对应只有一个索引的数列的情况。对于有两个不同索引的数列递推式,单一变量的生成函数不再适用,我们需要添加另外的一个变量y来构造双变量的生成函数B(x,y)。这种情况。在排列组合问题中,双索引的数列是非常常见的。例如,给定非负整数n,k且0≤k≤n,我们能从{1,2,⋯,n}中得到多少个不同的k子集。
此时我们假设f(n,k)是该问题的解,我们可以非常容易的得到下面的递推式
(15)f(n,k)=f(n−1,k)+f(n−1,k−1)w.r.t.f(n,0)=1
此时我们定义一个新的生成函数
根据原来的递推公式15,我们可以得到
(17)Bn(x)−1=(Bn−1(x)−1)+xBn−1(x)⇒Bn(x)=(1+x)Bn−1(x)⇒Bn(x)=(1+x)n⇒f(n,k)=(nk)
对付一些简单的双索引递推公式,我们很多时候用单变量的生成函数即可处理。然而,不是所有的双索引递推都是这么简单的。考虑下面的一个排列组合的例子:将一个大小为n的集合分割为k个不为空的子集。例如n=4,k=2时,其不同划分有如下几种:
(18)(12),(34);(13),(24);(14),(23);(123),(4);(124),(3);(134),(2);(234)(1)
我们用f(n,k)来代表其不同的子集划分数。根据{n}这个元素是否单独作为一个集合,我们可以把原来的问题分为两种情况:
是单独集合,原问题规约到了将n−1个元素划分为k−1子集的问题,此时的子集划分个数为f(n−1,k−1);
不是单独集合,此时对于任意的一个n−1元素的k划分,元素n可以插入到这k个划分的任意一个集合中,此时的子集划分个数为f(n−1,k)∗k。
所以,我们有如下的递推式:
(19)f(n,k)=f(n−1,k−1)+kf(n−1,k)w.r.t.n≥k≥0
此时,我们设
由此定义我们可以得到:
(21)Bk(x)=∑nf(n,k)xn=∑n(f(n−1,k−1)xn+kf(n−1,k)xn=x∑nf(n−1,k−1)xn−1+kx∑nf(n−1,k)xn−1=xBk−1(x)+kxBk(x)
所以,我们可以得到Bk(x)的解析式为
(22)Bk(x)=x1−kxBk−1(x)=xk(1−x)(1−2x)(1−3x)⋯(1−kx)
现在我们的问题就在于如何求出后面的展开式。为此,我们定义一个记号[xn]B(x)为函数B(x)展开式中xn的系数。此时
(23)f(n,k)=[xn]{xk(1−x)(1−2x)(1−3x)⋯(1−kx)}=[xn−k]{1(1−x)(1−2x)(1−3x)⋯(1−kx)}=[xn−k]∑r=1kαr1−rx=∑r=1kαr[xn−k]11−rx=∑r=1kαrrn−k
在这里我们得到了一个看上去非常美的结果,但是其实目前还没啥用,因为我们还没有求出满足下式的常数αr。
(24)xk(1−x)(1−2x)(1−3x)⋯(1−kx)=∑i=1kαi1−ix
为了得到αr,我们又需要利用一些诡异的技巧。首先在上式两边都乘以1−rx,然后令x=1/r。此时右边就只剩下αr了。所以
(25)αr=1(1−1/r)(1−2/r)⋯(1−(r−1)/r)(1−(r+1)/r)⋯(1−k/r)=(−1)k−rrk−1(r−1)!(k−r)!
将此式带入之前的式子,可得
(26)f(n,k)=∑r=1k(−1)k−rrnr!(k−r)!
现在是不是感觉很爽!
其实写本篇文章的动机是为了求解这个递推式
(27)f(m,n)=m∗(f(m−1,n−1)+f(m,n−1))n≥mf(m,m)=m!f(1,n)=1
该递推式的背景是一道微软的面试题,具体的内容忘记了。这是一个写代码的题,主要考察点是DP优化。但是正如前面所说的,我们可以直接求出其通项公式。其求解过程跟之前的基本一样.此时,我们设
(29)Bk(x)=∑nf(n,k)xn=k∑n(f(n−1,k−1)xn+f(n−1,k)xn=kx∑nf(n−1,k−1)xn−1+kx∑nf(n−1,k)xn−1=kx(Bk−1(x)+Bk(x))
(30)Bk(x)=kx1−kxBk−1(x)=xkk!(1−x)(1−2x)(1−3x)⋯(1−kx)
由此可得
(31)f(n,k)=k![xn]{xk(1−x)(1−2x)(1−3x)⋯(1−kx)}=k![xn−k]{1(1−x)(1−2x)(1−3x)⋯(1−kx)}=k![xn−k]∑r=1kαr1−rx=k!∑r=1kαr[xn−k]11−rx=k!∑r=1kαrrn−k=k!∑r=1k(−1)k−rrnr!(k−r)!
The Mother Function - spirits away
https://ift.tt/0paKevk
生成函数(mother function)是一种非常诡异的求数列通项的方法。核心思想是把数列的第项当作某个某个位置函数的系数系数。我们通过递推式来求得,然后将展开来得到的系数既是数列的通项:
下面我们就以几个循序渐进的例子来讲解这个生成函数方法的使用。
线性递推式是数列递推式中最简单的递推式,其形式如下:
其中为常数。这里为了简单起见,我们以为例来说明生成函数方法的使用。假设该数列的生成函数为,则我们可以得到
由此我们可以得到:
所以,通过这么长的递推,我们终于得到了,虽然说这个递推高一水平的人就可以做出来。但是我们总是会经历一个从这TM也需要证到这TM也能证的过程吧。
所谓伪线性递推是我生造的一个词,其递推结构与之前的一样,只不过可能为的线性表示。下面以例子来说明:
这里重复之前的推导过程,我们可以得到:
此时我们需要利用微积分的知识:
所以,我们将上式带入到之前,可以得到:
又因为
所以
斐波那契数列作为数列里面最经典的例子,本文自然不能放过。其数列递推式如下:
同样 ,设其生成函数为 ,我们可以得到
所以
然后经过一些稀里糊涂的中间步骤,我们可以得到
在上文中我们只涉及到了一个变量,此时对应只有一个索引的数列的情况。对于有两个不同索引的数列递推式,单一变量的生成函数不再适用,我们需要添加另外的一个变量来构造双变量的生成函数。这种情况。在排列组合问题中,双索引的数列是非常常见的。例如,给定非负整数且,我们能从中得到多少个不同的子集。
此时我们假设是该问题的解,我们可以非常容易的得到下面的递推式
此时我们定义一个新的生成函数
根据原来的递推公式,我们可以得到
对付一些简单的双索引递推公式,我们很多时候用单变量的生成函数即可处理。然而,不是所有的双索引递推都是这么简单的。考虑下面的一个排列组合的例子:将一个大小为的集合分割为个不为空的子集。例如时,其不同划分有如下几种:
我们用来代表其不同的子集划分数。根据这个元素是否单独作为一个集合,我们可以把原来的问题分为两种情况:
是单独集合,原问题规约到了将个元素划分为子集的问题,此时的子集划分个数为;
不是单独集合,此时对于任意的一个元素的划分,元素可以插入到这个划分的任意一个集合中,此时的子集划分个数为。
所以,我们有如下的递推式:
此时,我们设
由此定义我们可以得到:
所以,我们可以得到的解析式为
现在我们的问题就在于如何求出后面的展开式。为此,我们定义一个记号为函数展开式中的系数。此时
在这里我们得到了一个看上去非常美的结果,但是其实目前还没啥用,因为我们还没有求出满足下式的常数。
为了得到,我们又需要利用一些诡异的技巧。首先在上式两边都乘以,然后令。此时右边就只剩下了。所以
将此式带入之前的式子,可得
现在是不是感觉很爽!
其实写本篇文章的动机是为了求解这个递推式
该递推式的背景是一道微软的面试题,具体的内容忘记了。这是一个写代码的题,主要考察点是DP优化。但是正如前面所说的,我们可以直接求出其通项公式。其求解过程跟之前的基本一样.此时,我们设
由此定义我们可以得到:
所以,我们可以得到的解析式为
由此可得
via spiritsaway.info https://ift.tt/xtvPQyO
November 13, 2024 at 10:07AM