》》b站视频链接《《
OP
\
组合数和排列数
对于组合数(C)和排列数(A\P),从n个元素中选取m个,有
C n m = n ! m ! ( n − m ) ! A n m = C n m ⋅ m ! = n ! ( n − m ) ! C^m_n=\frac{n!}{m!(n-m)!}\\ \text{ }\\ A^m_n=C^m_n\cdotp m!=\frac{n!}{(n-m)!} Cnm=m!(n−m)!n! Anm=Cnm⋅m!=(n−m)!n!
关于组合数,以下推论均成立
C n m = n m C n − 1 m − 1 C n m = C n n − m C n m = C n − 1 m − 1 + C n − 1 m C_n^m=\frac n m C_{n-1}^{m-1}\\\text{ }\\ C_n^m=C_n^{n-m}\\\text{ }\\ C_n^m=C_{n-1}^{m-1}+C_{n-1}^m Cnm=mnCn−1m−1 Cnm=Cnn−m Cnm=Cn−1m−1+Cn−1m
组合数与杨辉三角
杨辉三角形如
1 1 1 1 2 1 1 3 3 1 1 4 6 4 1 1\\1\text{ }1\\1\text{ }2\text{ }1\\1\text{ }3\text{ }3\text{ }1\\1\text{ }4\text{ }6\text{ }4\text{ }1 11 11 2 11 3 3 11 4 6 4 1
不难发现,其中第 n 行的第 m 个数(从0开始)恰好为 C n m C_n^m Cnm 的值;
Lucas定理
求取 C n m % p C_n^m\%p Cnm%p 时,若 m , n 满足
n = n k p k + n k − 1 p k − 1 + . . . + n 1 p + n 0 m = m k p k + m k − 1 p k − 1 + . . . + m 1 p + m 0 n=n_kp^k+n_{k-1}p^{k-1}+...+n_1p+n_0\\\text{ }\\ m=m_kp^k+m_{k-1}p^{k-1}+...+m_1p+m_0 n=nkpk+nk−1pk−1+...+n1p+n0 m=mkpk+mk−1pk−1+...+m1p+m0
则有
C n m ≡ ∏ i = 0 k C n i m i ( m o d p ) C_n^m\equiv\prod_{i=0}^kC_{n_i}^{m_i}(\mod p) Cnm≡i=0∏kCnimi(modp)
也可以用递归表示:
C n m = l u c a s ( n , m ) ≡ C n % p m % p ⋅ l u c a s ( n p , m p ) ( m o d p ) C_n^m=lucas(n,m)\equiv C_{n\%p}^{m\%p}\cdotp lucas(\frac n p,\frac m p)(\mod p) Cnm=lucas(n,m)≡Cn%pm%p⋅lucas(pn,pm)(modp)
代码如下
//求C_a^b
ll comp(ll a,ll b,ll m){
if(a<b) return 0;
if(a==b) return 1;
if(b>a-b) b=a-b;
ll ans=1,ca=1,cb=1;
for(int i=0;i<b;i++){
ca=ca*(a-i)%m;
cb=cb*(b-i)%m;
}
ans=ca*qm(cb,m-2)%m;
return ans;
}
ll lucas(ll a,ll b,ll m){
ll ans=1;
while(a&&b){
ans=(ans*comp(a%m,b%m,m))%m;
a/=m;
b/=m;
}
return ans;
}
容斥原理
在计数时,必须注意没有重复,没有遗漏。为了使重叠部分不被重复计算,人们研究出一种新的计数方法,这种方法的基本思想是:先不考虑重叠的情况,把包含于某内容中的所有对象的数目先计算出来,然后再把计数时重复计算的数目排斥出去,使得计算的结果既无遗漏又无重复,这种计数的方法称为容斥原理。
摘自百科词条
公式如下,亦摘自上链
简单来说,容斥原理是一个不断修正偏差的过程,每一次都是在修正上一次所产生的重复 \ 遗漏;
错位排序
求 n 的全排列中,1~n 的每个数都不在初始位置的方案数;
n 的全排列有 n ! n! n! 个,减去其中至少有一个数在正确位置的情况 C n 1 ( n − 1 ) ! C_n^1(n-1)! Cn1(n−1)! ,刚刚减去的部分重复减去了至少两个数在正确位置的情况,应再加上 C n 2 ( n − 2 ) ! C_n^2(n-2)! Cn2(n−2)! ,刚刚加上的部分又重复加上了至少三个数在正确位置的情况,应再减去 C n 3 ( n − 3 ) ! C_n^3(n-3)! Cn3(n−3)! …
以此类推,n 的错排有
D
n
=
∑
i
=
0
n
C
n
i
(
n
−
i
)
!
(
−
1
)
i
D_n=\sum_{i=0}^nC_n^i(n-i)!(-1)^i
Dn=∑i=0nCni(n−i)!(−1)i ;
与此同时,错排有递推式
D
n
=
(
n
−
1
)
(
D
n
−
1
+
D
n
−
2
)
D_n=(n-1)(D_{n-1}+D_{n-2})
Dn=(n−1)(Dn−1+Dn−2) ;
在查阅这篇文章中,找到了错排的估计公式
D
n
=
⌊
n
!
e
+
1
2
⌋
D_n=\lfloor \frac {n!} e+\frac 1 2 \rfloor
Dn=⌊en!+21⌋ ;
m球n盒问题
- 球相同,盒可空
我们可以假设 m 个球和 n-1 个隔板共同排序,第一个隔板前面的在第一个盒,第二个隔板与第一个隔板之间的在第二个盒…第 n-1 个隔板和第 n-2 个隔板之间的在第 n-1 个盒,第 n-1 个隔板之后的在第 n 个盒;
由于 m 个球相同,那么 n-1 个隔板所在位置不同的情况有 C m + n − 1 n − 1 C_{m+n-1}^{\text{ }n-1} Cm+n−1 n−1 ,即在所有位置中选出 n-1 个位置的选法; - 球相同,盒不空
我们可以假设在 m 个球之间的 m-1 个空中插入 n-1 个隔板(每空至多一个隔板),那么 n-1 个隔板所在位置不同的情况有 C m − 1 n − 1 C_{\text{ }m-1}^{\text{ }n-1} C m−1 n−1 ,即在所有位置中选出 n-1 个位置的选法; - 球不同,盒可空
每一个球都有 n 种选法,即 n m n^m nm ; - 球不同,盒不空
容斥:全集减非法集;
全集即为 n m n^m nm ,其中至少有一个盒子空的情况有 C n 1 ( n − 1 ) m C_n^1(n-1)^m Cn1(n−1)m ,至少有两个盒子空的情况有 C n 2 ( n − 2 ) m C_n^2(n-2)^m Cn2(n−2)m ,由容斥原理,不同的情况有 ∑ i = 1 n C n i ( n − i ) m ( − 1 ) i \sum_{i=1}^{n}C_n^i(n-i)^m(-1)^i ∑i=1nCni(n−i)m(−1)i 种;
多重集的r-组合数
截图自清华大学出版社《离散数学(第三版)》
ED
\