【学习笔记】组合数学

Page Views Count

排列组合#

四个计数原理#

  • 加法原理:并列的方案数加和。

  • 乘法原理:叠加的方案数相乘。

  • 减法原理:正难则反,补集转换。

  • 除法原理:目测用处不大。

排列组合定义式#

Anm=n!(nm)!,Cnm=(nm)=n!m!(nm)!

组合数的一些变换 1#

最基本的对称性:

(nm)=(nnm)

根据定义得到:

(nk)=nk(n1k1)

可以考虑组合意义的一个变换:

(nm)(mk)=(nk)(nkmk)

根据杨辉三角得到:

(nm)=(n1m1)+(n1m)

进而推出(考虑杨辉三角上一纵列):

i=0n(ik)=1+i=k+1n(ik)=(k+1k+1)+i=k+1n(ik)=(n+1k+1)

Lucas 定理#

(nm)(nmodpmmodp)(n/pm/p)(modp)

证明:

(k+1)pkp+1(modp)

求组合数实际上就是求一个二项式的某一项,将 n,m 分解,n=ap+b,m=cp+d

(k+1)n(k+1)ap(k+1)b(kp+1)a(k+1)b(modp)

m 项就是:

(nm)km=(ac)kcp(bd)kd

所以上式成立。

于是在模 p 定义下,组合数可以拆分成 p 进制类的数。

组合数的一些求法#

  • 规模小数量多:杨辉三角预处理。

  • 规模数量适中:预处理阶乘以及逆元。

  • 规模大:Lucas 定理

特殊组合数 1#

  • 多重集排列数(xiai 组成的本质不同序列个数):

(nx1,x2,,xk)=n!i=1kxi!

  • 无限多重集组合数:等价于求 i=1kxi=n 非负整数解的个数。令 yi=xi+1,就是在求 i=1kyi=n+k 的正整数解个数,后者可以插板法:

(n+k1k1)

  • 圆排列:只需要在正常基础上去掉断点的枚举:

Qnm=Anmm

二项式系数#

二项式定理#

(x+y)n=i=0n(ni)xiyni

证明考虑组合意义,从 nx 中选取 i 个,其余为 y 的方案数即为某一项的系数。

组合数的一些变换 2#

二项式定理的两个特殊情况:

i=0n(ni)=2n

i=0n(1)i(ni)=[n=0]

对上一个式子中 n1 前提下的进一步解释:按考虑 i 的奇偶两边展开,也就是 n 个数选取奇数个和偶数个的方案数,显然前 n1 个任意选,最后一个按照要求补全即可,于是两边都是 2n1

一个加权的式子:

i=1ni(ni)=n2n1

第一种证明是基于上面提出一个分式的转换:

i=1ni(ni)=i=1ni×ni(n1i1)=i=0n1n(n1i)=n2n1

也可以写成二项式再求导:

i=0n(ni)xi=(1+x)ni=1ni(ni)xi1=n(1+x)n1

代入 x=1,即证。

接下来考虑扩展到 i2,在代入前式子的基础上处理:

i=1ni(ni)xi=n(1+x)n1xi=1ni2(ni)xi1=n[(n1)(1+x)n2x+(1+x)n1]

同样代入 x=1,得到:

i=1ni2(ni)=n(n+1)2n2

容斥原理#

经典容斥模型#

集合 U 中每个元素都满足一些属性 P,其中满足属性 Pi 的元素构成了集合 Ai,现在给定集合 S,欲求出至少满足 S 中一种属性的元素个数(并集),以及同时满足 S 中所有属性的元素个数(交集)。

|iSAi|=TS,T(1)|T|1|jTAj|

若求交集只需做一个补集转换:

|iSAi|=|U||iSAi¯|

我们现在对这个模型给出证明,目的是证明每个符合条件的元素都不重不漏的只计算了一次。

考虑前面二项式中选择个数为偶数奇数方案数的例子,和这里是有相同之处的,对于一个元素 i,其满足的属性集合为 Bi,那么当且仅当 TBi 是才会对 i 的数量产生影响,也就是枚举 Bi 的非空子集。

而这里恰好就是选取奇数做正贡献,选取偶数做负贡献,而空集情况已经排除,那么奇数贡献正好比偶数多 1,即证不重不漏。

所以容斥最好的地方在于,正常求解对属性卡的非常严,而转化成交集后,只需考虑给出的部分满足,不需要考虑不给出的部分不满足。

特殊组合数 2#

  • 有限多重集组合数(每个元素有一个 ni 的数量限制):考虑容斥,要求每个限制都满足,可容斥求至少一个限制不满足的方案,即枚举每一个超出限制的集合,其方案数是总数削去所有超过限制元素的 ni+1 后的普通答案。

(n+k1k1)TU,T(1)|T|1(n+kiT(ni+1)1k1)

  • 错位排列(满足编号与值均不相等的排列):

使用容斥原理的通项式:

Dn=n!k=1n(1)k1(nk)(nk)!=n!n!k=1n(1)k1k!=n!k=0n(1)kk!

于是简单推导可以得出第一个递推式:

Dn=nDn1+(1)n

如果考虑组合意义可以得出第二个递推式:

{D1=0D2=1Dn=(n1)(Dn1+Dn2)n3

考虑满足条件的排列第一个数字取值为 [2,n],因此实际是钦定 2 为首个数字后的方案数的 n1 倍。

当第二位上是 1 时,后面 n2 个位置就是标准的错排,也就是 Dn2,当第二位上不是 1 是,后面 n1 个位置各自有自己的限制(1 不能出现在第二位,其余不能出现在对应位置),也就是 Dn1,即证上式。

子集反演#

f(S)=TSg(T)g(S)=TS(1)|S||T|f(T)

f(S)=STg(T)g(S)=ST(1)|T||S|f(T)

正确性直接代入即可。

二项式反演#

考虑容斥模型中大小相同的集合对应函数值相等的特殊情况,令 f(n) 表示同时满足 n 个条件对应原集的方案数,g(n) 表示 n 个满足 n 个条件对应补集的方案数,其中 f(0)=g(0)=|U|

由容斥模型:

|iSAi|=|U||iSAi¯|=|U|+TS,T(1)|T||jTAj¯|

f(n)=g(0)+i=1n(1)i(ni)g(i)=i=0n(1)i(ni)g(i)

而原集与补集是相对概念,fg 彼此的表达形式应当相同。

f(n)=i=0n(1)i(ni)g(i)g(n)=i=0n(1)i(ni)f(i)

把左式的 (1)i 并入 g(i) 中,得到:

f(n)=i=0n(ni)g(i)g(n)=i=0n(1)ni(ni)f(i)

证明可以直接代入,运用组合数的恒等式。

继续扩展得到:

f(n)=i=mn(ni)g(i)g(n)=i=mn(1)ni(ni)f(i)

f(n)=i=nm(in)g(i)g(n)=i=nm(1)in(in)f(i)

这里 fg 的定义与容斥中的类似,分别表示钦定和恰好,恰好不用解释,而钦定不是至少,是 存在重复方案的,即枚举每个大小相等的子集,在保证满足这个子集的前提下其余任意,这样的方案数之和。

二项式反演可以同样可以由子集反演得到(是特殊情况)。

min-max 容斥#

先放出式子:

maxiSxi=TS,T(1)|T|1minjTxj

miniSxi=TS,T(1)|T|1maxjTxj

用语言描述就是:一个集合的最值等于其所有非空子集的另一最值做出的容斥。

证明考虑对于从小到大第 k 的值,映射到一个 [1,k] 的整数集合,取 min 等价于集合取交集,而 max 等价于取并集,这样相当于是就全集映射到的集合之并,自然等价于各个子集映射到的集合之交。

思考 minmax 同时总能想到 gcdlcm,于是有:

lcmiSxi=TS,T(gcdjTxj)(1)|T|1

另外期望具有线性性,于是,就可以有:

E(maxiSxi)=TS,T(1)|T|1E(minjTxj)

这个用处很大,对于期望的问题,有时要求满足多个条件的期望,即求最大值的期望,而这往往不好求,相对简单的是去求一个集合的最小值期望,这是我们只需要关心什么时候首次满足条件即可。

特殊计数序列#

Catalan 数#

考虑一个由 n+1n1 构成的序列,要求这个序列任意一个前缀和都是非负数,求序列个数。

容易得到总的序列个数应当为 C2nn,现在想要求出不合法的方案数。

对于一个不合法序列,找到第一个不满足的位置,截至这个位置的前缀是 k+1k+11 组成的,把这个前缀每个位置取相反数,从而得到一个 n+1+1n11 构成的序列,这样的序列有:C2nn+1 个。

得到 Catalan 数的第一个表达式:

Cn=(2nn)(2nn+1)=(2nn)n+1

进一步可以得到递推式:

Cn=4n2n+1Cn1

考虑 Catalan 数的组合意义就是上面提到的 +11 序列,概括的说是在任意时刻,一种元素的个数总是不少于另一种,于是得到两个比较经典的模型:

  • (0,0) 走到 (n,n),每次可以纵向或横向增加一个单位,要求任意时刻所在位置 (x,y) 保证 xy,求方案数。(横向移动次数不少于纵向移动次数)

  • n 对括号构成的合法括号序列方案数。(左括号个数不少于右括号个数)

  • n 个元素入栈出栈顺序。(入栈次数不少于出栈次数)

对于上面的第二个例子,我们单独拿出最左侧的左括号以及其对应的右括号,这样会将整个括号序列划分成两个互不影响的合法子序列,枚举两个子序列大小得到:

Cn=i=0n1Ci×Cn1i

观察这种划分成两个部分的组合意义,这等价于 n 个节点构成二叉树的方案数。

第一类 Stirling 数#

定义#

定义 [nm] 为第一类 Stirling 数,将 n 个元素形成 m 个圆排列(两个圆之间无顺序差别)的方案数,

递推式:

[nm]=[n1m1]+(n1)[n1m]

性质#

每个圆排列集合都唯一对应一个置换(每个圆是一个循环置换),而置换有 n! 个,于是:

i=0n[ni]=n!

上升幂转普通幂:

xn¯=i=0n[ni]xi

归纳法证明:

xn+1¯=xn¯×(x+n)=i=0n[ni]xi×(x+n)=i=0n+1[ni1]xi+i=0nn[ni]xi=i=0n+1[n+1i]xi

由于上升幂与下降幂的关系:

xn¯=(1)n×(x)n_

xn_=(1)n×(x)n¯

代入到上面即可得到下降幂转普通幂:

xn_=i=0n(1)ni[ni]xi

第二类 Stirling 数#

定义#

定义 {nm} 为第一类 Stirling 数,将 n 个元素划分到 m 个非空集合(两个集合之间无顺序差别)的方案数。

递推式:

{nm}={n1m1}+m{n1m}

使用二项式反演可得另一通项公式:

gn(m)n 个元素放入 m 个集合(可以为空,两个集合之间有顺序差别)的方案数,显然 gn(m)=mn

fn(m)n 个元素放入 m 个集合(不能为空,两个集合之间有顺序差别)的方案数,有:

gn(m)=i=0m(mi)fn(i)

二项式反演得到:

fn(m)=i=0m(1)mi(mi)gn(i)

f 与第二类 Stirling 数的唯一区别是集合是否有顺序差别,也就是:

{nm}=f(m)m!=i=0m(1)miini!(mi)!

性质#

普通幂转下降幂(或者是组合数):

xn=i=0n{ni}xi_=i=0n{ni}i!(xi)=i=0n(xi)j=0i(ij)(1)ijjn

这里证明可以用组合意义,xn 即为 n 个元素放入 x 个有顺序差别集合中的方案数,枚举有 i 个集合非空,其选取方案、放置方案以及顺序差别三者的积即为上式。

实际应用中,通常转为组合数后进行组合数的变换。

同样的方式得到普通幂转上升幂:

xn=i=0n(1)ni{ni}xi¯

参考资料#

  • OI Wiki

  • 《组合数学》- Richard A. Brualdi

作者:SoyTony

出处:https://www.cnblogs.com/SoyTony/p/Learning_Notes_about_Combinatorics.html

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   SoyTony  阅读(573)  评论(8编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
more_horiz
keyboard_arrow_up light_mode palette
选择主题
menu
点击右上角即可分享
微信分享提示