设 0!=00=1。
施工中。有部分空缺。
加法 & 乘法原理
加法原理
完成一个任务有 n 类办法,第 i 类办法有 ai 个方法,则完成该任务共有 ∑i=1nai 种不同的方法。
乘法原理
完成一个任务有 n 个步骤,第 i 个步骤有 ai 个方法,则完成该任务共有 ∏i=1nai 种不同的方法。
排列 & 组合数
排列数
从 n 个互不相同的元素中取出 m(m≤n,m,n∈N)个并按照一定的顺序排列,所得到的排列称为 n 中取 m 的一个排列。设完成这个任务的方案数(也是所得排列的个数)为 Anm,有计算 Anm 的公式
Anm=n×(n−1)×⋯×(n−(m−1))=i=1∏m(n−(i−1))=(n−m)!n!(1)
(1) 可以用乘法原理解释。上述任务共分 m 步,其中第 i 步执行“从剩余 (n−(i−1)) 个元素中取出 1 个”,显然第 i 步有 (n−i+1) 个方案,于是累乘。
组合数
从 n 个互不相同的元素中取出 m(m≤n,m,n∈N)个组成集合,所得到的集合称为 n 中取 m 的一个组合,设所得的组合个数(重复的不计)为 Cnm=(mn)。
显然的,对于每个组合 C,都可以得出 m! 个以 C 内元素组成的排列。(只需将 C 内 m 个元素全排列即可。)于是,
m!(mn)=Anm
于是有计算 (mn) 的公式
(mn)=m!Anm=(n−m)!m!n!(2)
在 OI 中,由于 m>n 的情况对于定义无意义,故设此时 Anm=(mn)=0,代表无方案。(一般地,无意义的情况组合、排列数均默认为 0。)
圆排列
多重组合数
杨辉三角
容易通过下面将要介绍的 (3) 式得到杨辉三角 ⟺ 组合数。
这里给出一个表格
The table of (mn)n\m0123456789011111111111123456789213610152128363141020355684415153570126516215612661728847183681991
将组合数操作转化到为杨辉三角上研究是一个常用方法。下面的性质也可以结合杨辉三角理解(下面的部分可能偏形式化)。
组合数常见性质(公式)
对称公式
(kn)=(n−kn)(3)
即对换取与不取(C⇆∁{1,⋯,n}C)。
加法公式(递推式)
(kn)=(kn−1)+(k−1n−1)(4)
可视为最后一个元素取与不取之和。不取则从 n−1 中选 k,取则从 n−1 中选 k−1。
吸收公式
(kn)=kn(k−1n−1)(5)
由通项公式 (2) 可得:
(kn)=(n−k)!k!n!=k×(n−k)!(k−1)!n×(n−1)!=kn(k−1n−1)
二次选择
(mn)(km)=(kn)(m−kn−k)(6)
设 ∣A∣=n,∣B∣=m,∣C∣=k,C⊆B⊆A,则
从 A 中选出 B,再从 B 中选出 C 的方案数 等于 先从 A 中选出 C,然后从 ∁AC 中选出 B′,则 B=B′∪C 的方案数。
换个角度,使用定义,
(mn)(km)=(n−m)!m!n!×(m−k)!k!m!=(n−m)!n!×(m−k)!k!1=k!n!×(m−k)!(n−m)!1=(n−k)!k!n!×(m−k)!(n−m)!(n−k)!=(kn)(m−kn−k)
行求和
i=0∑n(in)=2n(7)
即所有选择的方案数等于所有长度为 i 的方案数之和(0≤i≤n)。
换个角度,由 (4) 得
i=0∑n(in)=i=0∑n[(i−1n−1)+(in−1)]=i=−1∑n−1(in−1)+i=0∑n(in−1)=2i=0∑n−1(in−1)
即行求和等于上一行求和的两倍。n=0 时,
i=0∑n(in)=(00)=1=20=2n
故运用数学归纳法可得式 (7)。
其实 (7) 式可由二项式定理代入 a=1,b=1 得到。下文会介绍。
带符号行求和
i=0∑n(−1)i(in)=[n=0](8)
同样由 (4) 得(n=0 时)
i=0∑n(−1)i(in)=i=0∑n(−1)i[(i−1n−1)+(in−1)]=(−1n−1)+(nn−1)=0
上面的推导运用了类似裂项的技巧,前后两项可以消去,只剩头尾。当 n=0 时,
i=0∑n(−1)i(in)=(−1)0×(00)=1
综上可得 (8)。同样,其可由二项式定理代入 a=1,b=−1 得到。
带权行求和
i=0∑ni(in)=n2n−1(9)
i=0∑ni2(in)=n(n+1)2n−1(10)
列求和
i=k∑n(ki)=(k+1n+1)(11)
考虑 (kk)=(k+1k+1)=1,
i=k∑n(ki)=(kk)+i=k+1∑n(ki)=(k+1k+1)+i=k+1∑n(ki)=(k+1k+1)+(kk+1)+i=k+2∑n(ki)=(k+1k+2)+i=k+2∑n(ki)⋮=(k+1k+j−1)+i=k+j−1∑n(ki)=(k+1k+j−1)+(kk+j−1)+i=k+j∑n(ki)=(k+1k+j)+i=k+j∑n(ki)⋮=(k+1k+(n−k+1))+i=k+(n−k+1)∑n(ki)=(k+1n+1)
很吓人?其实就是一行行地向下迭代。
主对角线(方向)求和
i=0∑k(in+i)=(kn+k+1)(12)
考虑 (0n)=(0n+1)=1,
i=0∑k(in+i)=(0n)+i=1∑k(in+i)=(0n+1)+i=1∑k(in+i)=(0n+1)+(1n+1)+i=2∑k(in+i)=(1n+2)+i=2∑k(in+i)⋮=(j−1n+j)+i=j∑k(in+i)⋮=((k+1)−1n+(k+1))+i=k+1∑k(in+i)=(kn+k+1)
辅对角线(方向)求和
i=0∑⌊2n⌋(in−i)=Fn+1(13)
其实累加上界并不重要,即上界是比较松的,因为 i>⌊2n⌋ 时 n−i<i,无意义。这里可以放大,视为 n,
i=0∑n(in−i)=i=0∑n[(in−i−1)+(i−1n−i−1)]=i=0∑n(in−i−1)+i=0∑n(i−1n−i−1)=i=0∑n(i(n−1)−i)+i=0∑n(i−1(n−2)−(i−1))=i=0∑n−1(i(n−1)−i)+i=0∑n−2(i(n−2)−i)
注意到上式满足斐波那契数列的递推式,同时 n=0 时式 (11) 等于 1,n=1 时式 (13) 也等于 1,故式 (13) 得证(数学归纳法)。
范德蒙德卷积
i=0∑k(in)(k−im)=(kn+m)(14)
证明使用二项式定理(设 l=i+j)
k=0∑n+m(kn+m)xkk=0∑n+m(kn+m)xk(kn+m)=(x+1)n+m=(x+1)n(x+1)m=[i=0∑n(in)xi][j=0∑m(jm)xj]=i=0∑nj=0∑m(in)(jm)xl=l=0∑n+mi=0∑l(in)(k−im)xl=l=0∑n+mi=0∑l(in)(k−im)xl=i=0∑l(in)(k−im)
换个角度,考虑其组合意义。设 ∣S∣=n,∣T∣=m,S,T 中的元素每个都相同。在大小 n+m 的集合 S∪T 中取出 k 个元素,等价于从 S 中取 i 个,T 中取 k−i 个,合并。取法二中,枚举 i 累加所有方案数,即与取法一方案数相等。
而上述意义是更利于记忆的。
推论 1
i=−a∑b(a+in)(b−im)=(a+bn+m)(15)
证明类似。同样可以用形式化证明或组合意义。
推论 2
i=1∑n(in)(i−1n)=(n−12n)(16)
考虑转化为 (14),
i=1∑n(in)(i−1n)=i=1∑n(n−in)(i−1n)=i=0∑n−1(n−1−in)(in)=(n−12n)
推论 3
i=0∑n(in)2=(n2n)(17)
依然转化,
i=0∑n(in)2=i=0∑n(in)(n−in)=(n2n)
推论 4
i=0∑m(in)(im)=(mn+m)(18)
还是转化
i=0∑m(in)(im)=i=0∑m(in)(m−im)=(mn+m)
其中 (mn+m) 是网格图计数。设 (x,y) 表示 x 行 y 列,则从 (0,0) 走到 (n,m),共需向下 n 步、向右 m 步,总步数为 n+m,从中选出 m 步向右即为方案数 (mn+m)。
若先走 n 步,其中 i 步向右,则剩下 m 步需 m−i 步向左,为 (in)(m−im),枚举 i 累加也是答案。故左右相等。
插板法
问题
有 n 个完全相同的元素,将其分成 k 份,设第 i 份有 xi 个(∑i=1kxi=n),求方案数。
正整数
限制条件:∀1≤i≤k,xi>0。
考虑将 k−1 个板子插到 n−1 个空中,表示将 n 个元素分成 k 份,由于 n 个元素又是完全相同的,于是答案即为 (k−1n−1)=(n−kn−1)。
非负整数
限制条件:∀1≤i≤k,xi≥0。
考虑加入 k 个同样的元素,均分给 k 份(每份都有 1 个)。设现在第 i 份有 xi′ 个,于是有 xi′=xi+1≥1>0,转化成了正整数情况。于是我们算出 x′ 的取值个数后,xi=xi′−1,即可得到 x 相对应的非负整数情况。显然对于每个 x,x′,二者是一一对应的。
于是,有答案 (k−1n+k−1)=(nn+k−1)。
更一般的限制情况
限制条件:∀1≤i≤k,xi≥ai≥0,其中设 ∑a=∑i=1kai≤n。
考虑转化成非负整数限制,我们从第 i 份中偷走 ai 个。设现在第 i 份有 xi′ 个,有 xi′=xi−ai。
设
n′=i=1∑kxi′=i=1∑kxi−i=1∑kai=n−∑a
故 x′ 取值个数为
(n′n′+k−1)=(n−∑an−∑a+k−1)
求出 x′ 取值个数后,将偷走的元素还回去,即可一一对应得到相同取值个数的 x,故答案即为上式。
不相邻组合个数
从 n 中选 k 的组合 C,要求 ∀i,j∈C,i=j+1,求满足这样条件的 C 的个数。
考虑将选的 k 个数视为板,将未选的 n−k 个数视为相同的元素,将 k 个板插进 n−k+1 个空中(空包括两侧),满足了板两两不相邻,即问题的要求,于是答案即为 (kn−k+1)。
容斥原理
对于集合 U 中的元素,有 n 个互不相同的属性。拥有第 i 种属性的元素构成集合 Si。注意一个元素可能有多个属性。
我们有
∣∣∣∣∣∣i=1⋃nSi∣∣∣∣∣∣=j=1∑n(−1)j−11≤a(k)<a(k+1)≤n∑∣∣∣∣∣∣i=1⋂jSa(i)∣∣∣∣∣∣(19)
可以通过统计每个元素贡献得证。
同时若求全集 U 下的集合并,可得
∣∣∣∣∣∣i=1⋂nSi∣∣∣∣∣∣=∣∣∣∣∣∣i=1⋃nSi∣∣∣∣∣∣=∣U∣−∣∣∣∣∣∣i=1⋃nSi∣∣∣∣∣∣=∣U∣−j=1∑n(−1)j−11≤a(k)<a(k+1)≤n∑∣∣∣∣∣∣i=1⋂jSa(i)∣∣∣∣∣∣=∣U∣+j=1∑n(−1)j1≤a(k)<a(k+1)≤n∑∣∣∣∣∣∣i=1⋂jSa(i)∣∣∣∣∣∣(20)
用容斥,不过用完容斥不是又要求并了吗?
二项式定理
二项式定理阐明了一个二项多项式展开后的系数与组合数的关系
(a+b)n=i=0∑n(in)aibn−i(21)
可以用组合意义证明,比较显然。
二项式反演
二项式反演为一种反演形式,常用于通过 “指定某若干个” 求 “恰好若干个” 的问题。——GXZlegend
第 0 形式
∣∣∣∣∣∣i=1⋂nSi∣∣∣∣∣∣=∣U∣−∣∣∣∣∣∣i=1⋃nSi∣∣∣∣∣∣=∣U∣+j=1∑n(−1)j1≤a(k)<a(k+1)≤n∑∣∣∣∣∣∣i=1⋂jSa(i)∣∣∣∣∣∣∣∣∣∣∣∣i=1⋂nSi∣∣∣∣∣∣=∣U∣−∣∣∣∣∣∣i=1⋃nSi∣∣∣∣∣∣=∣U∣+j=1∑n(−1)j1≤a(k)<a(k+1)≤n∑∣∣∣∣∣∣i=1⋂jSa(i)∣∣∣∣∣∣
当集合的交集大小只与所交的集合的数量有关时,若设 f(j) 表示任意 j 个集合的补集的交集大小,g(j) 表示任意 j 个集合的交集大小,即
f(j)≡∣∣∣∣∣∣i=1⋂jSa(i)∣∣∣∣∣∣(∀1≤ak<ak+1≤n)g(j)≡∣∣∣∣∣∣i=1⋂jSa(i)∣∣∣∣∣∣(∀1≤ak<ak+1≤n)
代入,
f(n)=∣U∣+j=1∑n(−1)j1≤a(k)<a(k+1)≤n∑g(j)=j=0∑n(−1)j(jn)g(j)g(n)=∣U∣+j=1∑n(−1)j1≤a(k)<a(k+1)≤n∑f(j)=j=0∑n(−1)j(jn)f(j)
这里之所以 ∣U∣ 能被吸收进 sigma 中是因为 ∩ 的单位元是全集 U。当 j=0 时,(−1)j(jn)g(j)=1×1×g(0)=∣U∣。
于是我们得到了二项式反演的第 0 形式:
f(n)=j=0∑n(−1)j(jn)g(j)⟺g(n)=j=0∑n(−1)j(jn)f(j)(22)
第 1 形式
考虑设 h(j)=(−1)jg(j),代入,
f(n)=j=0∑n(jn)h(j)⟺(−1)nh(n)=j=0∑n(−1)j(jn)f(j)⟺h(n)=j=0∑n(−1)n+j(jn)f(j)⟺h(n)=j=0∑n(−1)n−j(jn)f(j)
于是我们得到了二项式反演的第 1 形式:
f(n)=j=0∑n(jn)h(j)⟺h(n)=j=0∑n(−1)n−j(jn)f(j)(23)
第 1.5 形式
第 1 形式更加一般的情况,
f(n)=j=m∑n(jn)h(j)⟺h(n)=j=m∑n(−1)n−j(jn)f(j)(24)
考虑证明:
代入(记 k=j−i)
f(n)=j=m∑n(jn)i=m∑j(−1)j−i(ij)f(i)=j=m∑ni=m∑j(−1)j−i(jn)(ij)f(i)=j=m∑ni=m∑j(−1)j−i(in)(j−in−i)f(i)=i=m∑nj=i∑n(−1)j−i(in)(j−in−i)f(i)=i=m∑n(in)f(i)j=i∑n(−1)j−i(j−in−i)=i=m∑n(in)f(i)k=0∑n−i(−1)k(kn−i)=i=m∑n(in)f(i)[n−i=0]=(nn)f(n)=f(n)□
第 2 形式
f(n)=j=n∑m(nj)g(j)⟺g(n)=j=n∑m(−1)j−n(nj)f(j)(25)
证明与第 1.5 形式类似,略。简称懒得写了(。
康托展开
一些定义
有一个长度为 n 的排列 P。
定义排列通过字典序比大小,即若长度为 n 的排列 A,B 有
- 任意 1≤j<i≤n,Aj=Bj;
- Ai<Bi,
则有排列 A<B。这里不考虑长度不一样的情况。
定义一个排列 P 的排名 rnk(P) 为比它小的排列数量 +1。
康托展开
给定 P,求 rnk(P)。
等价于:求长度为 n 的排列 Q,满足 Q<P 的数量(+1)。
考虑枚举定义中的 i。于是 ∀1≤j<i≤n,Qj=Pj。那么 Qi 可以是哪些数呢?
- Qi<Pi⟹Qi=Pi⟹i=k。
- Qi=Qj⟺∃k,i≤k,Qi=Pk。
⟹∃k,i<k,Qi=Pk<Pi,故 Qi 的取值数量(记为 f(i))即为
f(i)=k=i+1∑n[Pk<Pi]
其中 [X] 表示条件 X 是真(1)/假(0)。
这是典型的二维偏序问题。可以用树状数组实现。
求出了 Qi 取值数量,考虑求 Qi+1∼Qn 的排列数量。
由于已经满足 Qi<Pi,故后面 (n−i) 个数可以随便排列,排列数量为 (n−i)!。故在 i 处小于 P 的排列数量为
(n−i)!×f(i)
将所有 i 的贡献相加,即可得到
rnk(P)=1+i=1∑n(n−i)!×f(i)
倒序枚举 i,f(i) 可以使用树状数组在 O(logn) 时间计算,故该算法可以在 O(nlogn) 时间内计算某个排列的排名,被称为康托展开。
逆康托展开
排名可以逆推得到排列。
但可以发现有 n=20 时,全排列数量 n!=2432902008176640000>1018。
所以,若题目给的排名 rnk(P)≤1018(不需要高精),有 n=∣P∣≤20。
于是,我们可以完成如下 n 次操作:
- 设 r0=rnk(P)−1,集合 S={1,2,⋯,n}。
- 对于第 j 次操作,rj←rj−1mod(n−j)!,kj←(n−j)!rj−1−rj。
- 从 S 中取出第 (kj+1) 大的元素 x,有 Pj=x。从 S 中删除 x。
- 重复进行上面两步 n 次。
解释一下:
每次操作从 rj−1 中分离出 f(j),以 j=1 为例
r0=i=1∑n(n−i)!×f(i)r1←r0mod(n−1)!=(i=1∑n(n−i)!×f(i))mod(n−1)!=i=1∑n((n−i)!×f(i)mod(n−1)!)=((n−1)!×f(1)mod(n−1)!)+i=2∑n((n−i)!×f(i)mod(n−1)!)=i=2∑n((n−i)!×f(i)mod(n−1)!)∵∴∴∴∴f(i)=k=i+1∑n[Pk<Pi]≤n−i<n−i+1(n−i)!×f(i)<(n−i)!×(n−i+1)=(n−i+1)!≤(n−1)!(n−i)!×f(i)<(n−1)!(n−i)!×f(i)mod(n−1)!=(n−i)!×f(i)r1←i=2∑n((n−i)!×f(i)mod(n−1)!)=i=2∑n(n−i)!×f(i)
有没有发现 r1 与 r0 几乎一致(除了 sigma 下界从 1 变成 2)?
对于 k1,
k1←(n−1)!r0−r1=(n−1)!∑i=1n(n−i)!×f(i)−∑i=2n(n−i)!×f(i)=(n−1)!(n−1)!×f(1)=f(1)
如此这般,我们进行了完美的迭代,每次将 f(j) 分离,从 S 中找出合适的 x。然后将 rj−1 中 i=j 那项消去(simga 上界加 1)。
形式化地说,我们的处理方式使得有 rj,kj 的通项公式
rj=i=j+1∑n(n−i)!×f(i)kj=f(j)
S 可以用 vector
维护,复杂度 O(n2)。因为 n≤20,复杂度足够。
若毒瘤出题人让 rnk(P)>1018,也不要紧。上线段树二分维护 S 即可。
抽屉原理
简单情况
对于 n+1 个物品分为 n 组,必存在某组分到的物品数大于 1 个。
显然的,可以用反证法证明。
一般情况
对于 n 个物品分到 k 组,必存在某组分到的物品数大于等于 ⌈kn⌉ 个。
反证法:若每一组均小于 ⌈kn⌉ 个,则由 ⌈kn⌉<kn+1 可得
n≤(⌈kn⌉−1)×k<(kn+1−1)×k=n
矛盾。
错位排列
定义
对于长度为 n 的排列 P,若 ∀1≤i≤n,Pi=n,则称它是一个错位排列。
设 Dn 为长度为 n 的错位排列数,求 Dn。
基于容斥原理
考虑容斥解决。我们有全集 U 为 n 的全排列(∣U∣=n!),n 个属性,第 i 个为 Pi=i。
我们有(这里去掉了 1≤a(k)<a(k+1)≤n 方便展示)
Dn=∣∣∣∣∣∣i=1⋂nSi∣∣∣∣∣∣=∣U∣−∣∣∣∣∣∣i=1⋃nSi∣∣∣∣∣∣=∣U∣+j=1∑n(−1)ja(k)∑∣∣∣∣∣∣i=1⋂jSa(i)∣∣∣∣∣∣(26)
考虑上式的意义。可以发现 ∣∣∣∣⋂i=1jSa(i)∣∣∣∣ 即为满足 Pa(i)=ai 的排列数量,固定的共有 j 位,剩下 n−j 为可以随意选择,于是有 (n−j)! 个排列。
同时,选择出 j 个 ai 方案数为 (jn),故
Dn=∣U∣+j=1∑n(−1)ja(k)∑∣∣∣∣∣∣i=1⋂jSa(i)∣∣∣∣∣∣=∣U∣+j=1∑n(−1)j(jn)(n−j)!=(−1)0(0n)n!+j=1∑n(−1)jj!(n−j)!n!×(n−j)!=j=0∑n(−1)jj!n!=n!j=0∑nj!(−1)j(26)
另外,观察到式 (26) 的形式与 ex 类似
exe−1en!=i=0∑∞i!xi=i=0∑∞i!(−1)i≈n!i=0∑ni!(−1)i=Dn
我们有 Dn≈en!。除了美观,没什么用。
基于递推
对于 n 的错排,暂且假设 Pn=n,有以下两种方式可以一步将 P 改成错排
- 若 P1∼Pn−1 是错排,那么任意 1≤i<n,交换 Pi,Pn 即可。i 有 n−1 个可能的取值,P1∼Pn−1 错排方案数为 Dn−1。
- 若 P1∼Pn−1 不是错排,有且只有一个位置 i,满足 Pi=i,那么依然交换 Pi,Pn。同样的,i 有 n−1 个可能的取值,而除 i 外的其他部分为错排,方案数为 Dn−2。
于是得到
Dn=(n−1)Dn−1+(n−1)Dn−2=(n−1)(Dn−1+Dn−2)(27)
另有
Dn=nDn−1+(−1)n
常见数(列)
斐波那契数列
定义
斐波那契数列的定义如下:
Fi=⎩⎪⎪⎨⎪⎪⎧01Fi−1+Fi−2i=0i=1otherwise(28)
同时我们有卢卡斯数列:
Li=⎩⎪⎪⎨⎪⎪⎧21Li−1+Li−2i=0i=1otherwise(29)
计算
斐波那契数列可以 O(n) 递推计算,但还有更快的计算方法。
我们有斐波那契数列的通项公式:
Fn=5(21+5)n−(21−5)n(30)
在模意义下有意义。平常用不到。
对于卢卡斯数列:
Fn=(21+5)n+(21−5)n(31)
当然,可以使用矩阵加速递推
[FnFn+1]=[Fn−1Fn][0111]=[F0F1][0111]n(32)
于是运用矩阵快速幂,我们可以 O(logn) 时间内计算斐波那契数列。
也可以使用倍增的技巧。考虑斐波那契数列的递推式,对它进行拓展
Fi+1Fi+2=Fi+1+FiFi+3=Fi+2+Fi+1Fi+4=Fi+3+Fi+2Fi+5=Fi+4+Fi+3=Fi+Fi−1=2Fi+Fi−1=3Fi+2Fi−1=5Fi+3Fi−1=8Fi+5Fi−1
可得:
Fi+jF2kF2k+1=Fj+1Fi+FjFi−1=Fk+1Fk+FkFk−1=FkFk+1+Fk(Fk+1−Fk)=Fk(2Fk+1−Fk)=Fk+1Fk+1+FkFk−1+1=Fk+12+Fk2(33)
1 2 3 4 5 6 7 8
| std::pair<int,int> fib(int n) { if(!n)return {0,1}; auto r=fib(n>>1); int c=p.first*(2*p.second-p.first), d=p.first*p.first+p.second*p.second; return (n&1)?{d,c+d}:{c+d}; }
|
性质
- Fn−1Fn+1−Fn2=(−1)n;
- (33) 式;
- ∀k∈N,Fn∣Fnk;
- ∀Fa∣Fb,a∣b;
- gcd(Fa,Fb)=Fgcd(a,b);
- 以斐波那契数列相邻两项作为输入会使欧几里德算法达到最坏复杂度。
卡特兰数
相关问题(应用)
卡特兰数列 Hn 一般应用于以下基本问题:
- 将大小为 n 的问题分解为规模之和为 n−1 的两个子问题。比如二叉树的构造方案数、不相交弦本质不同方案数、凸包三角形划分方案数等。
对于另一种看似也很基本的问题,其实可以转化为上述基本问题:
- 可以抽象为平面直角坐标系上行走的问题。具体的,从 (0,0) 走到 (2n,0),每次从 (x,y) 向右上 (x+1,y+1) 或右下 (x+1,y−1) 走,且不走到 x 轴下方,的路径方案数。如出栈序列数、买票找零等。以出栈序列数为例,可以证明出栈序列与操作序列是一一对应的,而操作序列中入栈操作可以视为向右上走,出栈可以视为向右下走,横坐标对应时间,纵坐标对应栈的大小,触碰 x 轴对应栈空。
如何将这种问题(2)转化为基本问题(1)呢?
对于这种问题,我们假设路径在 (2i,0) 处第一次触碰 x 轴(除起点外,可以是终点)。为了保证第一次,从 (0,0) 到 (2i,0) 的路径不能触碰 x 轴。怎样保证呢?考虑先从 (0,0) 走到 (1,1),然后保证路径不在 y=1 下方,即不会触碰 x 轴,走到 (2i−1,1)。然后在从 (2i−1,1) 走到 (2i,0),完成第一次触碰。接下来可以只需不走到 x 轴下方,从 (2i,0) 走到 (2n,0) 即可。
于是我们得到第一部分路径方案数为 Hi−1,第二部分则为 Hn−i。根据乘法原理和加法原理,我们枚举每个 i 即可得到
Hn=⎩⎪⎨⎪⎧1i=1∑nHi−1Hn−in=0,1otherwise(34)
而基本问题(1)的方案数显然也是上式。于是我们就得到了二问题等价。(34) 式为卡特兰数的一个递推式。
注:对于问题(2),其他资料中常有等价描述:设非降路径是指只能向上或向右走的路径,求不走到对角线 y=x 上方(但可以触碰)的情况下从 (0,0) 到达 (n,n) 的可能路径数。可以通过旋转、轴对称发现二描述等价。本文为了方便思考、与出栈序列问题相对应,采用了不同的描述方式。
公式
我们考虑问题(2)的组合意义。若不考虑“不走到 x 轴下方”这一限制条件,我们有答案 (n2n),即在 2n 步中,选出 n 步向右上,另外 n 步向右下。
考虑如何处理走到 x 轴下方的情况。对于所有不合法路径(即走到 x 轴下方的路径),我们将第一次走到 x 轴下方之后的路径,即第一次触碰 y=−1 之后的路径,以 y=−1 为对称轴翻转。之前的路径不变。可以证明,翻转后的路径均可以和原路径一一对应。
如图,虚线为翻转前的不合法路径,点线为翻转后的路径,点划线则为二者公共部分。
经过观察,发现翻转后的路径从 (0,0) 走到 (2n,−2)。即在 2n 步中选出 n−1 步向右上,其他向右下的路径。方案数为 (n−12n)。将全部方案减去不合法方案,即得到全部合法方案数为:
Hn=(n2n)−(n−12n)(35)
进一步地,
HnHn=(n2n)−(n−12n)=n!n!(2n)!−(n−1)!(n+1)!(2n!)Let t=(n−1)!=(2n)![n2t21−n(n+1)t21]=t2n(2n)!(n1−n+11)=t2n(2n)!×n(n+1)n+1−n=t2n2(n+1)(2n)!=n!n!(n+1)(2n)!=n+1(n2n)(36)
更进一步,
HnHn=t2n2(n+1)(2n)!=(n−1)!(n−1)!n2(n+1)(2n−2)!(2n)(2n−1)=n(n−12n−2)×n(n+1)2n(2n−1)=n+1Hn−1(4n−2)(37)
这便是最简单的递推式。至此,所有卡特兰数的公式证毕。
第二类斯特林数
第二类斯特林数,也称斯特林子集数,记做 {nk},表示将 n 个互不相同的元素,划分为 k 个相同的非空子集的方案数。
递推式
⎩⎪⎨⎪⎧[n=0]{nk}={n−1k−1}+k{n−1k}k=0otherwise(38)
可以使用组合意义证明。对于第 n 个物品,
- 若新开一个集合,则方案数为 {n−1k−1};
- 若将其放入现有的 k 个集合(中的任意一个),方案数为 k{n−1k}。
通项公式
第一类斯特林数
参考