加法原理和乘法原理
一件事有若干个方法 → \to → 加法原理。
一件事有若干个步骤 → \to → 乘法原理。
例题
有 n n n 个不同的物品,放进 m m m 个排成一行的背包中,每个背包只放一个,使相邻两个背包的物品不相同。
第一个背包随便放,其余每个背包和前面的不一样,所以为 n × ( n − 1 ) m − 1 n \times (n-1)^{m-1} n×(n−1)m−1。
排列和组合
P n m = A n m = n ( n − 1 ) ( n − 2 ) ⋯ ( n − m + 1 ) = n ! ( n − m ) ! P_{n}^{m}=A_{n}^{m}=n(n-1)(n-2) \cdots(n-m+1)=\frac{n !}{(n-m) !} Pnm=Anm=n(n−1)(n−2)⋯(n−m+1)=(n−m)!n!
( n m ) = C n m = P n m P m = n ! m ! ( n − m ) ! {n \choose m} = C_{n}^{m}=\frac{P_{n}^{m}}{P_{m}}=\frac{n !}{m !(n-m) !} (mn)=Cnm=PmPnm=m!(n−m)!n!
C n 0 = 1 C n m = C n n − m C n + 1 m = C n m + C n m − 1 \begin{array}{l} \\ C_{n}^0 = 1 \\ C_{n}^{m}=C_{n}^{n-m} \\ C_{n+1}^{m}=C_{n}^{m}+C_{n}^{m-1} \end{array} Cn0=1Cnm=Cnn−mCn+1m=Cnm+Cnm−1
C n 2 = n ( n − 1 ) 2 C_{n}^{2}=\frac{n (n-1)}{2} Cn2=2n(n−1)
如何求组合数?
- O ( n 2 ) O(n^2) O(n2) 预处理杨辉三角。
- 在模数是质数的前提下, O ( n ) O(n) O(n) 预处理逆元和阶乘,用原公式。
如果不会 O ( n ) O(n) O(n) 预处理逆元也没关系。
1 m ! = 1 ( m + 1 ) ! × ( m + 1 ) \frac{1}{m!} = \frac{1}{(m+1)!} \times (m+1) m!1=(m+1)!1×(m+1)
所以可以用费马小定理 O ( log n ) O(\log n) O(logn) 求出 1 m ! \frac{1}{m!} m!1 的最后一项,再 O ( n ) O(n) O(n) 往前递推即可。
- 如果 n n n 极大, m m m 极小,且模数为质数。
C n m = P n m P m = n ( n − 1 ) ( n − 2 ) ⋯ ( n − m + 1 ) m ! C_{n}^{m}=\frac{P_{n}^{m}}{P_{m}} = \frac{n(n-1)(n-2) \cdots(n-m+1)}{m!} Cnm=PmPnm=m!n(n−1)(n−2)⋯(n−m+1)
可以发现上面有 m m m 项,下面也有 m m m 项,所以 O ( m ) O(m) O(m) 预处理上面,用之前的方法预处理 1 m ! \frac{1}{m!} m!1 即可。
如果 p p p 为任意值,可以 O ( m 2 ) O(m^2) O(m2) 暴力约分。
- m m m 和 n n n 都极大,且模数是质数,且模数较小——Lucas定理
Lucas定理
m = m k p k + m k − 1 p k − 1 + ⋯ + m 1 p + m 0 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}+\cdots+m_{1} p+m_{0} \\ n=n_{k} p^{k}+n_{k-1} p^{k-1}+\cdots+n_{1} p+n_{0} m=mkpk+mk−1pk−1+⋯+m1p+m0n=nkpk+nk−1pk−1+⋯+n1p+n0
( n m ) ≡ ∏ i = 0 k ( n i m i ) ( m o d p ) {n \choose m} \equiv \prod_{i=0}^{k} {n_i \choose m_i} \pmod p (mn)≡i=0∏k(mini)(modp)
用人话来说,就是将 n n n 和 m m m 写成 p p p 进制, p p p 为质数。对于进制的每一位对应的 n i n_i ni 和 m i m_i mi,求组合数,最后乘起来,得到的就是 ( n m ) n \choose m (mn)。在写代码时可以根据下方的式子
( n m ) = ( ⌊ n p ⌋ ⌊ m p ⌋ ) × ( n m o d p m m o d p ) ( p ∈ prime ) m o d p {n \choose m} = {\left\lfloor\frac{n}{p}\right\rfloor \choose \left\lfloor\frac{m}{p}\right\rfloor} \times {n \bmod p\choose m \bmod p} \quad(p \in \operatorname{prime}) \bmod p (mn)=(⌊pm⌋⌊pn⌋)×(mmodpnmodp)(p∈prime)modp
插板法
将 n n n 个相同的球,放入 m m m 个不同的盒子,没有空盒。方案数为
( n − 1 m − 1 ) n - 1 \choose m-1 (m−1n−1)
理解: n n n 个元素有 n − 1 n-1 n−1 个空,插入 m − 1 m-1 m−1 个木板就能分成 m m m 组。
如果每组至少分 2 2 2 个呢?可以现在 m m m 个盒子放上 m m m 个球,那么方案数为 ( n − m − 1 m − 1 ) n - m - 1 \choose m - 1 (m−1n−m−1)。
如果每组可以不分呢?先借每个盒子一个球,分的时候还给它们,那么方案数为 ( n + m − 1 m − 1 ) n+m-1 \choose m-1 (m−1n+m−1)。
卡特兰数
C n = 1 n + 1 ( 2 n n ) = ( 2 n ) ! ( n + 1 ) ! n ! C 0 = C 1 = 1 C 2 = 2 C 3 = 5 C 4 = 14 C 5 = 42 C 6 = 132 C_{n}=\frac{1}{n+1} {2n \choose n}=\frac{(2 n) !}{(n+1) ! n !} \\ C_{0} = C_{1} = 1 \quad C_{2} = 2\quad C_{3} = 5\quad C_{4} = 14\quad C_{5} = 42\quad C_{6} =132 Cn=n+11(n2n)=(n+1)!n!(2n)!C0=C1=1C2=2C3=5C4=14C5=42C6=132
有 C n C_n Cn 个长度为 2 n 2n 2n 的 01 01 01 序列,满足 ∀ i , ∃ count 1 , i ( 0 ) ≥ count 1 , i ( 1 ) \forall i,\exists \operatorname{count}_{1,i}(0) \ge\operatorname{count}_{1,i}(1) ∀i,∃count1,i(0)≥count1,i(1)。
常见应用:括号序列,出栈序列,矩阵从左上角走到右下角的方案数(只能向右、下走)。
考虑用组合意义推出 C n C_n Cn。
先忽略限制,那么有多少个长为 2 n 2n 2n 的 01 序列满足 count 1 , n ( 0 ) ≥ count 1 , n \operatorname{count}_{1,n}(0) \ge\operatorname{count}_{1,n} count1,n(0)≥count1,n。答案为在 2 n 2n 2n 个位置中选出 n n n 个位置填 0 0 0,即为 ( 2 n n ) 2n \choose n (n2n)。那么再求一下不合法的序列个数减掉即可。
找到第一个不合法的位置 i + 1 i +1 i+1,即为 a i + 1 = 0 a_{i+1} = 0 ai+1=0。那么有 count 1 ∼ i ( 0 ) = count 1 ∼ i ( 1 ) = i \operatorname{count}_{1 \sim i}(0) = \operatorname{count}_{1 \sim i}(1) = i count1∼i(0)=count1∼i(1)=i, count i + 2 ∼ n ( 0 ) = n − i , count i + 2 ∼ n ( 1 ) = n − i − 1 \operatorname{count}_{i+2 \sim n}(0) = n - i, \operatorname{count}_{i+2 \sim n}(1) = n - i - 1 counti+2∼n(0)=n−i,counti+2∼n(1)=n−i−1。
我们将 1 ∼ i + 1 1 \sim i + 1 1∼i+1 的数反转一下,即为 1 → 0 , 0 → 1 1\to 0,0 \to 1 1→0,0→1。那么 count ( 0 ) 1 ∼ i = count ( 1 ) = i 1 ∼ i \operatorname{count}(0)_{1 \sim i} = \operatorname{count}(1) = i_{1 \sim i} count(0)1∼i=count(1)=i1∼i, a i + 1 = 0 a_{i+1} = 0 ai+1=0, count ( 0 ) i + 2 ∼ n = n − i , count ( 1 ) i + 2 ∼ n = n − i − 1 \operatorname{count}(0)_{i+2 \sim n} = n - i, \operatorname{count}(1)_{i+2 \sim n} = n - i - 1 count(0)i+2∼n=n−i,count(1)i+2∼n=n−i−1。此时 count ( 0 ) 1 , n = n + 1 , count ( 1 ) 1 , n = n − 1 \operatorname{count}(0)_{1,n} = n + 1, \operatorname{count}(1)_{1,n} = n-1 count(0)1,n=n+1,count(1)1,n=n−1。
可以发现,在反转后的每个序列都对应着一个反转前的不合法序列。这意味着,只要满足 count ( 0 ) 1 , n = n + 1 , count ( 1 ) 1 , n = n − 1 \operatorname{count}(0)_{1,n} = n + 1, \operatorname{count}(1)_{1,n} = n-1 count(0)1,n=n+1,count(1)1,n=n−1,那么反转这个序列的一个前缀后就会得到一个新的不合法序列。
所以长为 2 n 2n 2n 的合法序列的个数为
( 2 n n ) − ( 2 n n + 1 ) ⟺ ( 2 n n ) − ( 2 n n − 1 ) = ( 2 n n ) n + 1 {2n \choose n} - {2n \choose n+1} \iff {2n \choose n} - {2n \choose n-1} = \frac{{2n \choose n}}{n+1} (n2n)−(n+12n)⟺(n2n)−(n−12n)=n+1(n2n)
错位排序
D n = ( n − 1 ) × ( D n − 1 + D n − 2 ) ( n > 2 ) D_{n}=(n-1) \times \left(D_{n-1}+D_{n-2}\right)(n>2) Dn=(n−1)×(Dn−1+Dn−2)(n>2)
D n D_n Dn 表示有多少个 1 ∼ n 1 \sim n 1∼n 的排列,满足 a i ≠ i a_i \neq i ai=i,即为不一一对应。
那么用组合意义推一下:
-
加入第 n n n 个元素时,前 n − 1 n-1 n−1个元素已经错排好。则选择其中任意一个与 a n a_n an 交换一定合法。则选择方法有 i − 1 i-1 i−1 种,记为 D n − 1 × ( n − 1 ) D_{n-1} \times (n-1) Dn−1×(n−1)
-
加入第 n n n 个元素时,前 n − 1 n-1 n−1 个元素只有一个元素满足 a i = i a_i = i ai=i,其它的已经错排好。那么将 a i a_i ai 与 a n a_n an 交换,那么现在 a n a_n an 还可以和 n − 2 n - 2 n−2 个元素交换,那么记为 D n − 2 × ( n − 1 ) D_{n-2} \times (n-1) Dn−2×(n−1)。
综上所述,伪证完毕。