基础组合计数和容斥原理
因为是数学,所以今天的代码会额外的少,我会分几个板块来阐述今天的内容。
一、基本计数原理
定义:若完成一件事的方法有
n 类,其中第
i 类方法包括
ai 种不同的方法,且这些方法互不重合,则完成这件事共有
a1+a2+a3+⋯+an 种不同的方法。
有点太偏理论了,我们来举个栗子:
如图,点
1 和点
2 之间有三条不同的路线,那么就有
1+1+1=3 种情况。
定义:若完成一件事需要
n 个步骤,其中第
i 个步骤有
ai 种不同的完成方法,且这些步骤互不干扰,则完成这件事共有
a1×a2×⋯×an 种不同的方法。
同样来举个栗子:
我们由上面的加法原理可知,点1到点2共有2种情况,点2到点3共有3种情况,则点1到点3共有
2×3=6 种情况。
讲完了基本计数原理,我们就可以学习下一个篇章了。
二、排列组合
顾名思义,就是指
从 n 个不同元素中选择 m 个元素有序排列的方案数,该数被称作
排列数,记作:
Anm 或
Pnm。
基本公式:Anm=(n−m)!n!
组合是指
从 n 个不同元素中选择 m 个元素组合的方案数(之间无序),记作
Cnm 或
(mn)。
基本公式:Cnm=(n−m)!m!n!
有了这些基础,我们有了以下推导。
- Cnm=Cn−1m−1+Cn−1m 其中边界条件为 C00=1,Ci0=1(组合计数的递推式)
- 求逆元:i!1=(i+1)!1×(i+1)
Lucas定理:对于质数
p≤n 的情况可以使用:
Cnm≡CnmodpmmodpC⌊pn⌋⌊pm⌋(modp)
由于此处重点,所以我提供了代码实现:
CPPint Lucas(int n,int m)
{
if(m == 0) return 1;
return C(n%p, m%p) * Lucas(n/p, m/p) % p;
}
(一)捆绑法
(二)插空法
(三)隔板法
- Cnk=Cnn−k
- k=0∑nCnk=2n (二项式定理拓展)
- CnmCmk=CnkCn−km−k
- i=m∑nCim=Cn+1m+1
有如下意义:
我们想求杨辉三角中一列数字之和(红框),只需要求出图中篮框数字即可。
- 范德蒙德卷积:i=0∑nCxiCyn−i=Cx+yn
- 二项式定理:(x+y)n=i=0∑nCnixiyn−i
- kCnk=nCn−1k−1
-
多重集的排列,设
S={n1a1,n2a2,...,nkak},其中
n1+n2+⋅⋅⋅+nk=n,其排列数为
n1!n2!...nk!n!。
-
多重集的组合,
S={n1a1,n2a2,...,nkak},r≤ni(∀iϵ[1,k]) ,从
S 中取出
r 个元素组成一个多重集,产生的不同多重集的数量为
Ck+r−1k−1 。
三、容斥原理
在计数时,必须注意没有重复,没有遗漏。为了使重叠部分不被重复计算,人们研究出一种新的计数方法,这种方法的基本思想是:先不考虑重叠的情况,把包含于某内容中的所有对象的数目先计算出来,然后再把计数时重复计算的数目排斥出去,使得计算的结果既无遗漏又无重复,这种计数的方法称为容斥原理。
∣A∪B∣:集合A与B的并集大小。
∣A∩B∣:集合A与B的交集大小。
-
∣A∪B∣=∣A∣+∣B∣−∣A∩B∣
-
∣A∪B∪C∣=∣A∣+∣B∣+∣C∣−∣A∩B∣−∣A∩C∣−∣B∩C∣+∣A∩B∩C∣
设
A1,A2,…,An 是有限集合,则它们的并集的大小为:
i=1⋃nAi=i=1∑n∣Ai∣−1≤i<j≤n∑∣Ai∩Aj∣+1≤i<j<k≤n∑∣Ai∩Aj∩Ak∣−⋯+(−1)n+1i=1⋂nAi
简记形式:
i=1⋃nAi=∅=S⊆{1,2,…,n}∑(−1)∣S∣+1j∈S⋂Aj
概率版本:
对于概率空间中的事件
A1,A2,…,An:
P(i=1⋃nAi)=k=1∑n(−1)k+11≤i1<⋯<ik≤n∑P(Ai1∩⋯∩Aik)
总结
"千里之行,始于足下。" —— 老子
面对困难与挑战,遥远的路途,我们要敢于向前,敢于拼搏,走出属于自己的路,走出踏踏实实的路。
向着理想的银河迈进!