排列组合是组合数学中的基础。排列就是指从给定个数的元素中取出指定个数的元素进行排序;组合则是指从给定个数的元素中仅仅取出指定个数的元素,不考虑排序。排列组合的中心问题是研究给定要求的排列和组合可能出现的情况总数。排列组合与古典概率论关系密切。
在高中初等数学中,排列组合多是利用列表、枚举等方法解题。
完成一个工程可以有 n n n 类办法, a i ( 1 ≤ i ≤ n ) a_i(1 \le i \le n) ai(1≤i≤n) 代表第 i i i 类方法的数目。那么完成这件事共有 S = a 1 + a 2 + ⋯ + a n S=a_1+a_2+\cdots +a_n S=a1+a2+⋯+an 种不同的方法。
完成一个工程需要分 n n n 个步骤, a i ( 1 ≤ i ≤ n ) a_i(1 \le i \le n) ai(1≤i≤n) 代表第 i i i 个步骤的不同方法数目。那么完成这件事共有 S = a 1 × a 2 × ⋯ × a n S = a_1 \times a_2 \times \cdots \times a_n S=a1×a2×⋯×an 种不同的方法。
从 n n n 个不同元素中,任取 m m m ( m ≤ n m\leq n m≤n , m m m 与 n n n 均为自然数,下同)个元素按照一定的顺序排成一列,叫做从 n n n 个不同元素中取出 m m m 个元素的一个排列;从 n n n 个不同元素中取出 m m m ( m ≤ n m\leq n m≤n ) 个元素的所有排列的个数,叫做从 n n n 个不同元素中取出 m m m 个元素的排列数,用符号 A n m \mathrm A_n^m Anm (或者是 P n m \mathrm P_n^m Pnm )表示。
排列的计算公式如下:
A n m = n ( n − 1 ) ( n − 2 ) ⋯ ( n − m + 1 ) = n ! ( n − m ) ! \mathrm A_n^m = n(n-1)(n-2) \cdots (n-m+1) = \frac{n!}{(n - m)!} Anm=n(n−1)(n−2)⋯(n−m+1)=(n−m)!n!
n ! n! n! 代表 n n n 的阶乘,即 6 ! = 1 × 2 × 3 × 4 × 5 × 6 6! = 1 \times 2 \times 3 \times 4 \times 5 \times 6 6!=1×2×3×4×5×6 。
公式可以这样理解: n n n 个人选 m m m 个来排队 ( m ≤ n m \le n m≤n )。第一个位置可以选 n n n 个,第二位置可以选 n − 1 n-1 n−1 个,以此类推,第 m m m 个(最后一个)可以选 n − m + 1 n-m+1 n−m+1 个,得:
A n m = n ( n − 1 ) ( n − 2 ) ⋯ ( n − m + 1 ) = n ! ( n − m ) ! \mathrm A_n^m = n(n-1)(n-2) \cdots (n-m+1) = \frac{n!}{(n - m)!} Anm=n(n−1)(n−2)⋯(n−m+1)=(n−m)!n!
全排列: n n n 个人全部来排队,队长为 n n n 。第一个位置可以选 n n n 个,第二位置可以选 n − 1 n-1 n−1 个,以此类推得:
A n n = n ( n − 1 ) ( n − 2 ) ⋯ 3 × 2 × 1 = n ! \mathrm A_n^n = n(n-1)(n-2) \cdots 3 × 2 × 1 = n! Ann=n(n−1)(n−2)⋯3×2×1=n!
全排列是排列数的一个特殊情况。
从 n n n 个不同元素中,任取 m m m ( m ≤ n m\leq n m≤n ) 个元素组成一个集合,叫做从 n n n 个不同元素中取出 m m m 个元素的一个组合;从 n n n 个不同元素中取出 m m m ( m ≤ n m\leq n m≤n ) 个元素的所有组合的个数,叫做从 n n n 个不同元素中取出 m m m 个元素的组合数。用符号 C n m \mathrm C_n^m Cnm 来表示。
组合数计算公式
C n m = A n m m ! = n ! m ! ( n − m ) ! \mathrm C_n^m = \frac{\mathrm A_n^m}{m!} = \frac{n!}{m!(n - m)!} Cnm=m!Anm=m!(n−m)!n!
如何理解上述公式?我们考虑 n n n 个人 m m m ( m ≤ n m \le n m≤n ) 个出来,不排队,不在乎顺序 C n m C_n^m Cnm 。如果在乎排列那么就是 A n m A_n^m Anm ,如果不在乎那么就要除掉重复,那么重复了多少?同样选出的来的 m m m 个人,他们还要“全排”得 A n m A_n^m Anm ,所以得:
C n m × m ! = A n m C n m = A n m m ! = n ! m ! ( n − m ) ! \mathrm C_n^m \times m! = \mathrm A_n^m\\ \mathrm C_n^m = \frac{\mathrm A_n^m}{m!} = \frac{n!}{m!(n-m)!} Cnm×m!=AnmCnm=m!Anm=m!(n−m)!n!
组合数也常用 ( n m ) \displaystyle \binom{n}{m} (mn) 表示,读作「 n n n 选 m m m 」,即 C n m = ( n m ) \displaystyle \mathrm C_n^m=\binom{n}{m} Cnm=(mn) 。实际上,后者表意清晰明了,美观简洁,因此现在数学界普遍采用 ( n m ) \displaystyle \binom{n}{m} (mn) 的记号而非 C n m \mathrm C_n^m Cnm 。
组合数也被称为「二项式系数」,下文二项式定理将会阐述其中的联系。
特别地,规定当 m > n m>n m>n 时, A n m = C n m = 0 \mathrm A_n^m=\mathrm C_n^m=0 Anm=Cnm=0 。
在进入排列组合进阶篇之前,我们先介绍一个与组合数密切相关的定理——二项式定理。
二项式定理阐明了一个展开式的系数:
( a + b ) n = ∑ i = 0 n ( n i ) a n − i b i (a+b)^n=\sum_{i=0}^n\binom{n}{i}a^{n-i}b^i (a+b)n=i=0∑n(in)an−ibi
证明可以采用数学归纳法,利用 ( n k ) + ( n k − 1 ) = ( n + 1 k ) \displaystyle \binom{n}{k}+\binom{n}{k-1}=\binom{n+1}{k} (kn)+(k−1n)=(kn+1) 做归纳。
二项式定理也可以很容易扩展为多项式的形式:
设 n 为正整数, x i x_i xi 为实数,
( x 1 + x 2 + ⋯ + x t ) n = ∑ 满足 n 1 + ⋯ + n t = n 的非负整数解 ( n n 1 n 2 ⋯ n t ) x 1 n 1 x 2 n 2 ⋯ x t n t (x_1 + x_2 + \cdots + x_t)^n = \sum_{满足 n_1 + \cdots + n_t=n 的非负整数解} \binom{n}{n_1n_2\cdots n_t} x_1^{n_1}x_2^{n_2}\cdots x_t^{n_t} (x1+x2+⋯+xt)n=满足n1+⋯+nt=n的非负整数解∑(n1n2⋯ntn)x1n1x2n2⋯xtnt
其中的 ( n n 1 , n 2 , ⋯ , n t ) \binom{n}{n_1,n_2,\cdots ,n_t} (n1,n2,⋯,ntn) 是多项式系数,它的性质也很相似:
∑ ( n n 1 n 2 ⋯ n t ) = t n \sum{\binom{n}{n_1n_2\cdots n_t}} = t^n ∑(n1n2⋯ntn)=tn
接下来我们介绍一些排列组合的变种。
请大家一定要区分 多重组合数 与 多重集的组合数 !两者是完全不同的概念!
多重集是指包含重复元素的广义集合。设 S = { n 1 ⋅ a 1 , n 2 ⋅ a 2 , ⋯ , n k ⋅ a k , } S=\{n_1\cdot a_1,n_2\cdot a_2,\cdots,n_k\cdot a_k,\} S={n1⋅a1,n2⋅a2,⋯,nk⋅ak,} 表示由 n 1 n_1 n1 个 a 1 a_1 a1 , n 2 n_2 n2 个 a 2 a_2 a2 ,…, n k n_k nk 个 a k a_k ak 组成的多重集, S S S 的全排列个数为
n ! ∏ i = 1 k n i ! = n ! n 1 ! n 2 ! ⋯ n k ! \frac{n!}{\prod_{i=1}^kn_i!}=\frac{n!}{n_1!n_2!\cdots n_k!} ∏i=1kni!n!=n1!n2!⋯nk!n!
相当于把相同元素的排列数除掉了。具体地,你可以认为你有 k k k 种不一样的球,每种球的个数分别是 n 1 , n 2 , ⋯ , n k n_1,n_2,\cdots,n_k n1,n2,⋯,nk ,且 n = n 1 + n 2 + … + n k n=n_1+n_2+\ldots+n_k n=n1+n2+…+nk 。这 n n n 个球的全排列数就是 多重集的排列数 。多重集的排列数常被称作 多重组合数 。我们可以用多重组合数的符号表示上式:
( n n 1 , n 2 , ⋯ , n k ) = n ! ∏ i = 1 k n i ! \binom{n}{n_1,n_2,\cdots,n_k}=\frac{n!}{\prod_{i=1}^kn_i!} (n1,n2,⋯,nkn)=∏i=1kni!n!
可以看出, ( n m ) \displaystyle \binom{n}{m} (mn) 等价于 ( n m , n − m ) \displaystyle \binom{n}{m,n-m} (m,n−mn) ,只不过后者较为繁琐,因而不采用。
设 S = { n 1 ⋅ a 1 , n 2 ⋅ a 2 , ⋯ , n k ⋅ a k , } S=\{n_1\cdot a_1,n_2\cdot a_2,\cdots,n_k\cdot a_k,\} S={n1⋅a1,n2⋅a2,⋯,nk⋅ak,} 表示由 n 1 n_1 n1 个 a 1 a_1 a1 , n 2 n_2 n2 个 a 2 a_2 a2 ,…, n k n_k nk 个 a k a_k ak 组成的多重集。那么对于整数 r ( r < n i , ∀ i ∈ [ 1 , k ] ) r(r
( r + k − 1 k − 1 ) \binom{r+k-1}{k-1} (k−1r+k−1)
考虑这个问题:设 S = { n 1 ⋅ a 1 , n 2 ⋅ a 2 , ⋯ , n k ⋅ a k , } S=\{n_1\cdot a_1,n_2\cdot a_2,\cdots,n_k\cdot a_k,\} S={n1⋅a1,n2⋅a2,⋯,nk⋅ak,} 表示由 n 1 n_1 n1 个 a 1 a_1 a1 , n 2 n_2 n2 个 a 2 a_2 a2 ,…, n k n_k nk 个 a k a_k ak 组成的多重集。那么对于正整数 r r r ,从 S S S 中选择 r r r 个元素组成一个多重集的方案数。
这样就限制了每种元素的取的个数。同样的,我们可以把这个问题转化为带限制的线性方程求解:
∀ i ∈ [ 1 , k ] , x i ≤ n i , ∑ i = 1 k x i = r \forall i\in [1,k],\ x_i\le n_i,\ \sum_{i=1}^kx_i=r ∀i∈[1,k], xi≤ni, i=1∑kxi=r
于是很自然地想到了容斥原理。容斥的模型如下:
于是设满足属性 i i i 的集合是 S i S_i Si , S i ‾ \overline{S_i} Si 表示不满足属性 i i i 的集合,即满足 x i ≥ n i + 1 x_i\ge n_i+1 xi≥ni+1 的集合。那么答案即为
∣ ⋂ i = 1 k S i ∣ = ∣ U ∣ − ∣ ⋃ i = 1 k S i ‾ ∣ \left|\bigcap_{i=1}^kS_i\right|=|U|-\left|\bigcup_{i=1}^k\overline{S_i}\right| i=1⋂kSi =∣U∣− i=1⋃kSi
根据容斥原理,有:
∣ ⋃ i = 1 k S i ‾ ∣ = ∑ i ∣ S i ‾ ∣ − ∑ i , j ∣ S i ‾ ∩ S j ‾ ∣ + ∑ i , j , k ∣ S i ‾ ∩ S j ‾ ∩ S k ‾ ∣ − ⋯ + ( − 1 ) k − 1 ∣ ⋂ i = 1 k S i ‾ ∣ = ∑ i ( k + r − n i − 2 k − 1 ) − ∑ i , j ( k + r − n i − n j − 3 k − 1 ) + ∑ i , j , k ( k + r − n i − n j − n k − 4 k − 1 ) − ⋯ + ( − 1 ) k − 1 ( k + r − ∑ i = 1 k n i − k − 1 k − 1 ) \begin{aligned} \left|\bigcup_{i=1}^k\overline{S_i}\right| =&\sum_i\left|\overline{S_i}\right| -\sum_{i,j}\left|\overline{S_i}\cap\overline{S_j}\right| +\sum_{i,j,k}\left|\overline{S_i}\cap\overline{S_j}\cap\overline{S_k}\right| -\cdots\\ &+(-1)^{k-1}\left|\bigcap_{i=1}^k\overline{S_i}\right|\\ =&\sum_i\binom{k+r-n_i-2}{k-1} -\sum_{i,j}\binom{k+r-n_i-n_j-3}{k-1}+\sum_{i,j,k}\binom{k+r-n_i-n_j-n_k-4}{k-1} -\cdots\\ &+(-1)^{k-1}\binom{k+r-\sum_{i=1}^kn_i-k-1}{k-1} \end{aligned} i=1⋃kSi ==i∑ Si −i,j∑ Si∩Sj +i,j,k∑ Si∩Sj∩Sk −⋯+(−1)k−1 i=1⋂kSi i∑(k−1k+r−ni−2)−i,j∑(k−1k+r−ni−nj−3)+i,j,k∑(k−1k+r−ni−nj−nk−4)−⋯+(−1)k−1(k−1k+r−∑i=1kni−k−1)
拿全集 ∣ U ∣ = ( k + r − 1 k − 1 ) \displaystyle |U|=\binom{k+r-1}{k-1} ∣U∣=(k−1k+r−1) 减去上式,得到多重集的组合数
A n s = ∑ p = 0 k ( − 1 ) p ∑ A ( k + r − 1 − ∑ A n A i − p k − 1 ) Ans=\sum_{p=0}^k(-1)^p\sum_{A}\binom{k+r-1-\sum_{A} n_{A_i}-p}{k-1} Ans=p=0∑k(−1)pA∑(k−1k+r−1−∑AnAi−p)
其中 A 是充当枚举子集的作用,满足 ∣ A ∣ = p , A i < A i + 1 |A|=p,\ A_i
1 ∼ n 1 \sim n 1∼n 这 n n n 个自然数中选 k k k 个,这 k k k 个数中任何两个数都不相邻的组合有 ( n − k + 1 k ) \displaystyle \binom {n-k+1}{k} (kn−k+1) 种。
我们把错位排列问题具体化,考虑这样一个问题:
n n n 封不同的信,编号分别是 1 , 2 , 3 , 4 , 5 1,2,3,4,5 1,2,3,4,5 ,现在要把这五封信放在编号 1 , 2 , 3 , 4 , 5 1,2,3,4,5 1,2,3,4,5 的信封中,要求信封的编号与信的编号不一样。问有多少种不同的放置方法?
假设我们考虑到第 n n n 个信封,初始时我们暂时把第 n n n 封信放在第 n n n 个信封中,然后考虑两种情况的递推:
对于第一种情况,前面 n − 1 n-1 n−1 个信封全部装错:因为前面 n − 1 n-1 n−1 个已经全部装错了,所以第 n n n 封只需要与前面任一一个位置交换即可,总共有 f ( n − 1 ) × ( n − 1 ) f(n-1)\times (n-1) f(n−1)×(n−1) 种情况。
对于第二种情况,前面 n − 1 n-1 n−1 个信封有一个没有装错其余全部装错:考虑这种情况的目的在于,若 n − 1 n-1 n−1 个信封中如果有一个没装错,那么我们把那个没装错的与 n n n 交换,即可得到一个全错位排列情况。
其他情况,我们不可能通过一次操作来把它变成一个长度为 n n n 的错排。
于是可得错位排列的递推式为 f ( n ) = ( n − 1 ) ( f ( n − 1 ) + f ( n − 2 ) ) f(n)=(n-1)(f(n-1)+f(n-2)) f(n)=(n−1)(f(n−1)+f(n−2)) 。
错位排列数列的前几项为 0 , 1 , 2 , 9 , 44 , 265 0,1,2,9,44,265 0,1,2,9,44,265 。
n n n 个人全部来围成一圈,所有的排列数记为 Q n n \mathrm Q_n^n Qnn 。考虑其中已经排好的一圈,从不同位置断开,又变成不同的队列。
所以有
Q n n × n = A n n ⟹ Q n = A n n n = ( n − 1 ) ! \mathrm Q_n^n \times n = \mathrm A_n^n \Longrightarrow \mathrm Q_n = \frac{\mathrm A_n^n}{n} = (n-1)! Qnn×n=Ann⟹Qn=nAnn=(n−1)!
由此可知部分圆排列的公式:
Q n r = A n r r = n ! r × ( n − r ) ! \mathrm Q_n^r = \frac{\mathrm A_n^r}{r} = \frac{n!}{r \times (n-r)!} Qnr=rAnr=r×(n−r)!n!
由于组合数在 OI 中十分重要,因此在此介绍一些组合数的性质。
( n m ) = ( n n − m ) (1) \binom{n}{m}=\binom{n}{n-m}\tag{1} (mn)=(n−mn)(1)
相当于将选出的集合对全集取补集,故数值不变。(对称性)
( n k ) = n k ( n − 1 k − 1 ) (2) \binom{n}{k} = \frac{n}{k} \binom{n-1}{k-1}\tag{2} (kn)=kn(k−1n−1)(2)
由定义导出的递推式。
( n m ) = ( n − 1 m ) + ( n − 1 m − 1 ) (3) \binom{n}{m}=\binom{n-1}{m}+\binom{n-1}{m-1}\tag{3} (mn)=(mn−1)+(m−1n−1)(3)
组合数的递推式(杨辉三角的公式表达)。我们可以利用这个式子,在 O ( n 2 ) O(n^2) O(n2) 的复杂度下推导组合数。
( n 0 ) + ( n 1 ) + ⋯ + ( n n ) = ∑ i = 0 n ( n i ) = 2 n (4) \binom{n}{0}+\binom{n}{1}+\cdots+\binom{n}{n}=\sum_{i=0}^n\binom{n}{i}=2^n\tag{4} (0n)+(1n)+⋯+(nn)=i=0∑n(in)=2n(4)
这是二项式定理的特殊情况。取 a = b = 1 a=b=1 a=b=1 就得到上式。
∑ i = 0 n ( − 1 ) i ( n i ) = 0 (5) \sum_{i=0}^n(-1)^i\binom{n}{i}=0\tag{5} i=0∑n(−1)i(in)=0(5)
二项式定理的另一种特殊情况,可取 a = 1 , b = − 1 a=1, b=-1 a=1,b=−1 。
∑ i = 0 m ( n i ) ( m m − i ) = ( m + n m ) ( n ≥ m ) (6) \sum_{i=0}^m \binom{n}{i}\binom{m}{m-i} = \binom{m+n}{m}\ \ \ (n \geq m)\tag{6} i=0∑m(in)(m−im)=(mm+n) (n≥m)(6)
拆组合数的式子,在处理某些数据结构题时会用到。
∑ i = 0 n ( n i ) 2 = ( 2 n n ) (7) \sum_{i=0}^n\binom{n}{i}^2=\binom{2n}{n}\tag{7} i=0∑n(in)2=(n2n)(7)
这是 ( 6 ) (6) (6) 的特殊情况,取 n = m n=m n=m 即可。
∑ i = 0 n i ( n i ) = n 2 n − 1 (8) \sum_{i=0}^ni\binom{n}{i}=n2^{n-1}\tag{8} i=0∑ni(in)=n2n−1(8)
带权和的一个式子,通过对 ( 3 ) (3) (3) 对应的多项式函数求导可以得证。
∑ i = 0 n i 2 ( n i ) = n ( n + 1 ) 2 n − 2 (9) \sum_{i=0}^ni^2\binom{n}{i}=n(n+1)2^{n-2}\tag{9} i=0∑ni2(in)=n(n+1)2n−2(9)
与上式类似,可以通过对多项式函数求导证明。
∑ l = 0 n ( l k ) = ( n + 1 k + 1 ) (10) \sum_{l=0}^n\binom{l}{k} = \binom{n+1}{k+1}\tag{10} l=0∑n(kl)=(k+1n+1)(10)
可以通过组合意义证明,在恒等式证明中较常用。
( n r ) ( r k ) = ( n k ) ( n − k r − k ) (11) \binom{n}{r}\binom{r}{k} = \binom{n}{k}\binom{n-k}{r-k}\tag{11} (rn)(kr)=(kn)(r−kn−k)(11)
通过定义可以证明。
∑ i = 0 n ( n − i i ) = F n + 1 (12) \sum_{i=0}^n\binom{n-i}{i}=F_{n+1}\tag{12} i=0∑n(in−i)=Fn+1(12)
其中 F F F 是斐波那契数列。
∑ l = 0 n ( l k ) = ( n + 1 k + 1 ) (13) \sum_{l=0}^n \binom{l}{k} = \binom{n+1}{k+1}\tag{13} l=0∑n(kl)=(k+1n+1)(13)
通过组合分析——考虑 S = a 1 , a 2 , ⋯ , a n + 1 S={a_1, a_2, \cdots, a_{n+1}} S=a1,a2,⋯,an+1 的 k + 1 k+1 k+1 子集数可以得证。