组合数学杂记(一)

P.S
这个排版非常难堪
等闲暇之余修改之
继续读书笔记
组合数学 第五版
TBC
转载请注明出处

排列与组合的生成

Stirling’s approximation

n!2πn(ne)nln(n!)=nln(n)+ln(2πn)2n

​ 公式证明可以百度之,通常可以使用这个公式来估算

n!
在十进制表示下的位数,例如POJ 1423。

排列

​ Even著作中给出一种排列的生成方式,值得关注的从逆序列构造原排列的两种算法。

​ 已知原排列的逆序列为

b1,b2,,bn

  • 算法一

    1. 写出
      n
    2. 依次考虑
      bnk,k=1,2,,n1
      ,将
      nk
      写在前一步的
      bnk
      个数后,特别地,若
      bnk=0
      ,则将放在
      0
      个数后,即放在序列的开头
  • 算法二

    依次考虑

    1,2,,n
    ,将
    n
    写在从左向右第
    bnk+1
    个空位置上

    ​算法一强调整数间的相对位置,算法二强调直接找到整数在原排列中应有的位置。算法二可以用树状数组来实现(或者更优的数据结构)。

组合

S n个元素的集合, S 2n个组合(子集)。生成算法的步骤和证明见书相关章节。生成算法给出子集之间的一个序关系。

  • S
    n
    -组合

    1. 二进制数顺序生成

    2. 基2算法

    3. 二进制

      n
      阶反射Gray码

      Gray码可以推广至任意基的系统

  • S
    r
    -组合

    按字典序的生成算法

二项式系数

​ Pascal公式(换言之,杨辉三角形),二项式定理和排列组合的恒等式这些内容比较基础。需要注意在证明一些结论时,常常使用了组合学的方法(应用加法原理、乘法原理等等),这要求一种不同的思维方式;同时也可以使用代数的方法,根据一些代数式的运算,用系数来证明结论,这与求解线性递推数列使用生成函数的方法遥相呼应,可以看做是理解生成函数法的一个启蒙吧。

​ 牛顿二项式定理?泰勒展开?好像这里又给生成函数埋了个伏笔。

(x+y)α=k=0(αk)xkyαk,αR,0|x|<|y|

也可以写成等价形式:

z=x/y,|z|<1:(1+z)α=k=0(αk)zk

容斥原理

​ 简单的就不说了,大家都会。留意多重集的处理。重数为有限数的不妨变换条件,计算重数为无穷大的情况,利用具有

k
种不同物体且每种物体都有无限重数的多重集
r
-组合的个数为
(r+k1r)
来计算集合中元素的个数。

线性递推数列

齐次递推关系的通解和非齐次递推关系的特解

​ 这种方法和求解线性微分方程神似。先求出对应的齐次递推关系特征方程,给出通解,在待定系数求非齐次递推关系的一组特解,解线性方程组,最后给出非齐次递推关系的通解。线性递推数列的线性性保证了这种方法的正确性,对

n
阶线性递推数列都可以成立。

生成函数

​ 令

h0,h1,h2,,hn,
为一无穷数列,其生成函数定义为无穷级数

g(x)=h0+h1x+h2x2++hnxn+

泰勒级数勒级数中每一项的系数看成对应组合数的计数,因而计数问题可以由生成函数直接求解。

​ 例:确定可以由苹果、香蕉、橘子和梨装水果的袋数

hn
,其中在每个袋子中苹果数是偶数,香蕉数是
5
的倍数,橘子数最多是
4
个,而梨的个数是
1
个或者
0
个。

​ 给出一个生成函数,有

g(x)=(1+x2+x4+)(1+x5+x10+)(1+x+x2+x3+x4)(1+x)=11x211x51x51x(1+x)=1(1x)2=n=0(n+1n)xn=n=0(n+1)xn

则有

hn=n+1

​ 同样地,线性齐次递推数列也可以用生成函数求解。

​ 例:求解满足初始值

h0=1
h1=2
的递推关系

hn=5hn16hn2,n2

g(x)=h0+h1x+h2x2++hnxn+
h_0,h_1,h_2,\cdots,h_n,\cdots
h0,h1,h2,,hn,
的生成函数。

\begin{aligned} g(x) &=h_0+h_1x+h_2x^2+\cdots+h_nx^n+\cdots \\ -5xg(x) &=-5xh_0x-5h_1x^2-\cdots-5h_{n-1}x^n-\cdots \\6x^2g(x) &=6h_0x^2+\cdots+6h_{n-2}x^n+\cdots \end{aligned} \\

g(x)5xg(x)6x2g(x)=h0+h1x+h2x2++hnxn+=5xh0x5h1x25hn1xn=6h0x2++6hn2xn+

(1-5x+6x^2)g(x) =h_0+(h_1-5h_0)x+(h_2-5h_1+6h_0)x^2+\cdots+(h_n-5h_{n-1}+6h_{n-2})x^n+\cdots \\

(15x+6x2)g(x)=h0+(h15h0)x+(h25h1+6h0)x2++(hn5hn1+6hn2)xn+

hn5hn1+6hn2=0,h0=1,h1=2

(15x+6x2)g(x)=h0+(h15h0)x=17x

g(x)=17x15x+6x2=17x(12x)(13x)=512x413x

g(x)=5(1+2x+22x2++2nxn+)4(1+3x+32x2++3nxn+)=n=0(5×2n4×3n)xn

hn=5×2n4×3n

当然,还有更一般化的结论。

​ 用单项式的集合

{1,x,x2,,xk,}
定义数列的生成函数,这比较适合设计二项式系数的序列。考虑到计算排列数的那些序列,用单项式集
{1,x,x22!,,xnn!,}
来生成函数更为有用。

​ 对多重集

{n1a1,n2a2,,nkak}
,其中
n1,n2,,nk
均为非负整数。
hn
S
n
-排列数。则序列
h0,h1,h2,,hn,
的指数生成函数

g(e)(x)=fn1(x)fn2(x)fnk(x)

fni(x)=1+x+x22!++xnini!

​ 证明及实例见书。

转移矩阵

​ 在我看来,上述两种方法适合手算,其实写程序不必这么辛酸。初始条件行向量,根据递推关系给出转移矩阵,用矩阵乘法并施以一定的优化就可以了。Fibonacci数列就是一个极好的例子。

几类特殊序列

  • 排列序列(阶乘序列)

  • 错位排列序列

    Dn=n!(111!+12!13!++(1)n1n!)

    ​ 可以使用容斥原理来推导,或者使用递推式从而求解特征方程;一些问题可转化为错位排列求解。联系一下

    ex
    的泰勒展式:

    1e=Dnn!+(1)n+11(n+1)!+(1)n+21(n+2)!+

    limnDnn!=1e

    事实上,

    Dn
    是最接近于
    n!e
    的整数。

    对此,我还没有考证这个“事实上”,这里暂时留待解决好了。

  • Fibonacci序列

    fn=15(1+52)n15(152)n

    ​ 公式推导可以使用特征方程法,关注转移矩阵。

  • Catalan数

    Cn=1n+1(2nn)

    n
    +1
    n
    1
    构成的
    2n

    a1,a2,,a2n

    其部分和满足

    a1+a2++ak0,(k=1,2,,2n)

    的数列的个数等于第

    n
    个Catalan数
    C2n

    定义一个新的数列

    C1,C2,,Cn,
    称为拟—Catalan数

    Cn=n!Cn1=(n1)!(2n2n1),(n1)

    a1,a2,,an
    n
    个数。我们说这些数的“乘法格式”是指进行
    a1,a2,,an
    的乘法的方案,一个乘法格式需要两数间的
    n1
    次乘法,这种乘法不满足交换律,这两书中的每一个或者是
    a1,a2,,an
    之一,或者是它们的部分乘积。令
    hn
    表示
    n
    个数的乘法格式的数目,则

    hn=Cn

    如果要求

    a1,a2,,an
    顺序,令
    gn
    表示有这种附加限制的乘法格式的数目,则

    gn=hnn!=1n(2n2n1),(n1)

    将具有

    n+1
    条边的凸多边形区域通过插入在区域内部不相交的对角线而分成三角形区域的方法数也为
    gn

  • Stirling数

    • 第一类Stirling数

    s(p,0)=0,(p1)s(p,p)=1,(p0)s(p,k)=(p1)s(p1,k)+s(p1,k1),(1kp1)

    第一类Stirling数

    s(p,k)
    是将
    p
    个物体排成
    k
    个非空的循环排列的方法数。

    [n]p={n(n1)(np+1),1,p1p=0

    [n]p=k=0p(1)pks(p,k)nk

    ​ 这才是书中对第一类Stirling数给出的定义。第一类Stirling数提供了用

    n0,n1,,np
    写出
    [n]p
    的方法。

    • 第二类Stirling数

    S(p,0)=0,(p1)S(p,p)=1,(p0)S(p,k)=kS(p1,k)+S(p1,k1),(1kp1)

    第二类Stirling数

    S(p,k)
    是将
    p
    个元素的集合划分成
    k
    个不可辨别的非空盒的划分的个数。

    ​ “不可辨别”意思盒子本身没有属性,例如颜色、大小、形状等等盒子的属性造成的划分不予考虑。

    S#(p,k)
    表示将
    p
    个元素分成
    k
    个非空、可辨别的盒子的划分数。用容斥原理可以证明

    S#(p,k)=k!S(p,k)=t=0p(1)t(kt)(kt)p

    S(p,k)=1k!t=0p(1)t(kt)(kt)p

    Bell数

    Bp
    是将
    p
    个元素划分成非空、不可辨别盒子的划分数。

    Bp=S(p,0)+S(p,1)++S(p,p)=t=0p1(p1t)Bp1t

    [n]k={n(n1)(nk+1),1,k1k=0

    np=k=0pS(p,k)[n]k

    ​ 这是书中对第二类Stirling数给出的定义。第二类Stirling数提供了用

    [n]0,[n]1,,[n]p
    写出
    np
    的方法。可以看成两组基的互换。

  • 分拆数

    pn

    n=0pnxn=k=111xk

  • n
    的前
    k+1
    个二项式系数的和
    h(k)n=i=0k(ni),(0kn)

    Δh(k)n=h(k1)n

    h(k)n
    是用
    n
    个一般位置上的
    k1
    -维超平面分割
    k
    -维空间所成的区域数。

  • 题外话:关于数列

    1k+2k++nk
    的计算

    ​ 不妨记

    f(n,k)=1k+2k++nk
    ,并且很容易计算

    f(n,0)f(n,1)f(n,2)=10+20++n0=n=11+21++n1=n(n+1)2=12+22++n2=n(n+1)(2n+1)6

    求解这个数列的方法是很多的,例如:

    • 累加与递推

    ​ 当我们已经求出了

    f(n,0),f(n,1),,f(n,k1)
    的显式表达式后,我们来求解
    f(n,k)

    (n+1)k+1nk+1[(n1)+1]k+1(n1)k+1(1+1)k+11k+1=(k+1)nk+i=0k1(k+1i)ni=(k+1)(n1)k+i=0k1(k+1i)(n1)i=(k+1)1k+i=0k1(k+1i)1i

    累加有

    (n+1)k+11=(k+1)f(n,k)+i=0k1(k+1i)f(n,i)

    ​ 代入

    f(n,0),f(n,1),,f(n,k1)
    即可解出
    f(n,k)

    • 线性方程组

    ​ 上一种方法的计算太过于复杂。可以归纳地得出,

    f(n,k)
    n
    k+1
    次多项式,那么,设

    g(n,k)=a0+a1n++ak+1nk+1

    并且要求

    g(n,k)g(n1,k)=nkg(0,k)=0

    f(n,k)=g(n,k)

    那么,

    a0=0
    。展开
    g(n,k)g(n1,k)

    i=1k+1ai[ni(n1)i]=nk

    ​ 比对系数,可以得到一个关于

    a1,a2,,ak+1
    的线性方程组,解这个线性方程组就可得到
    f(n,k)

    通过计算会发现,这个方程的系数矩阵规律性极其明显,举两例:

    k=3

    10001200133014640001

    k=4

    10000120001330014640151010500001

    f(n,k)
    得到一个
    (k+1)×(k+2)
    的系数矩阵。该系数矩阵的列向量
    αj,j=1,2,,k+2
    满足

    αj=((1)j+1(j0),(1)j+2(j1),,(1)j+j(jj1),0,0,,0)T(0,0,,0,1)T,1jk+1,j=k+2

    • 差分法

    ​ 计算

    nk
    的差分表,得到第
    0
    条对角线序列

    c0,c1,,ck,0,0,

    nk
    可以写成

    nk=j=0kcj(nj)

    又有

    i=0n(ij)=(n+1j+1)

    f(n,k)=i=0nik=i=0nj=0kcj(ij)=j=0kcj(n+1j+1)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值