定义
- 从 n n n个物品中选出 m m m个并考虑取出的先后顺序的方案数为 A n m A_n^m Anm。
- 从 n n n个物品中选出 m m m个不考虑先后顺序的方案数为 C n m C_n^m Cnm,同时也可以表示为 ( n m ) \binom{n}{m} (mn)。
- 其中 C n m C_n^m Cnm在计数题中出现更为频繁,所以接下来将基本围绕 C n m C_n^m Cnm展开。
如何求?
递推式
-
( n m ) = ( n − 1 m − 1 ) + ( n − 1 m ) \binom{n}{m}=\binom{n-1}{m-1}+\binom{n-1}{m} (mn)=(m−1n−1)+(mn−1)
-
靠这个计算是 O ( n ∗ m ) O(n*m) O(n∗m)的。
公式
-
( n m ) = n ! m ! ∗ ( n − m ) ! \binom{n}{m}=\frac{n!}{m!*(n-m)!} (mn)=m!∗(n−m)!n!
-
用这个计算是 O ( m ) O(m) O(m)的。
一些基本性质
1. ( n m ) = ( n n − m ) 2. ∑ i = 0 n ( n i ) = 2 n 3. ∑ i = 0 n ( − 1 ) i ∗ ( n i ) = 0 1.\binom{n}{m}=\binom{n}{n-m}\\ 2.\sum_{i=0}^n\binom{n}{i}=2^n\\ 3.\sum_{i=0}^n(-1)^i*\binom{n}{i}=0 1.(mn)=(n−mn)2.i=0∑n(in)=2n3.i=0∑n(−1)i∗(in)=0
一些很重要的技巧
简单的元素排列
- 有 m m m类元素,其中第 i i i类元素有 a i a_i ai个,问有多少种排列方案?
- 通过组合数可以简单得到方案数为 ( a 1 a 1 ) ∗ ( a 1 + a 2 a 2 ) ∗ ( a 1 + a 2 + a 3 a 3 ) ∗ . . . = ( a 1 + a 2 + a 3 + . . . + a n ) ! a 1 ! ∗ a 2 ! ∗ a 3 ! ∗ . . . ∗ a n ! \binom{a_1}{a_1}*\binom{a_1+a_2}{a_2}*\binom{a_1+a_2+a_3}{a_3}*...=\frac{(a_1+a_2+a_3+...+a_n)!}{a_1!*a_2!*a_3!*...*a_n!} (a1a1)∗(a2a1+a2)∗(a3a1+a2+a3)∗...=a1!∗a2!∗a3!∗...∗an!(a1+a2+a3+...+an)!。
如何求一列组合数的和
-
∑ i = m n ( i m ) = ( n + 1 m + 1 ) \sum_{i=m}^n\binom{i}{m}=\binom{n+1}{m+1} i=m∑n(mi)=(m+1n+1)
二项式定理
- ( a + b ) n = ∑ i = 0 n a i ∗ b n − i ∗ ( n i ) (a+b)^n=\sum_{i=0}^na^i*b^{n-i}*\binom{n}{i} (a+b)n=i=0∑nai∗bn−i∗(in)
卢卡斯定理
-
( n m ) ≡ ( n % p m % p ) ∗ ( n / p m / p ) ( m o d p ) \binom{n}{m} \equiv \binom{n\%p}{m\%p}*\binom{n/p}{m/p} (\mod p) (mn)≡(m%pn%p)∗(m/pn/p)(modp)
-
注意: p p p为质数。
-
经典问题: ( n m ) \binom{n}{m} (mn)要为奇数需要满足什么条件?
-
套用卢卡斯定理,考虑 p = 2 p=2 p=2的情况,
-
我们发现卢卡斯定理模拟的是把 n , m n,m n,m转化为二进制的过程。
-
考虑 n = a 1 a 2 a 3 . . . a p , m = b 1 b 2 b 3 . . . b q n=a_1a_2a_3...a_p,m=b_1b_2b_3...b_q n=a1a2a3...ap,m=b1b2b3...bq。
-
那么如果 ( n m ) \binom{n}{m} (mn)为偶数当且仅当存在一个 i i i使得 ( a i b i ) = 0 \binom{a_i}{b_i}=0 (biai)=0。
-
因为是转化为二进制,所以 0 < = a i , b i < = 1 0<=a_i,b_i<=1 0<=ai,bi<=1。
-
所以当 ( a i b i ) = 0 \binom{a_i}{b_i}=0 (biai)=0时, a i = 0 , b i = 1 a_i=0,b_i=1 ai=0,bi=1。
-
也就是说,假如 ( n m ) \binom{n}{m} (mn)为奇数,先将 n , m n,m n,m转化为二进制数,如果 m m m的某一位为1,则 n n n的对应为必为1,即 n ∧ m = m n \wedge m=m n∧m=m。
扩展卢卡斯定理
- 就是当 p p p不为质数是应该如何处理?
- 按照老套路,我们直接将 p p p分解质因数 p = a 1 b 1 ∗ a 2 b 2 ∗ a 3 b 3 ∗ . . . ∗ a k b k p=a_1^{b_1}*a_2^{b_2}*a_3^{b_3}*...*a_k^{b_k} p=a1b1∗a2b2∗a3b3∗...∗akbk。
- 我们只需要对于每一个质因数求出 ( n m ) m o d a i b i \binom{n}{m}\mod a_i^{b_i} (mn)modaibi,然后用中国剩余定理合并即可。
- 由于 m ! m! m!和 ( n − m ) ! (n-m)! (n−m)!有可能没有逆元,所以我们先把阶乘内所有 a i a_i ai的质因子提取出来。然后把所有 [ 1 , n ] , [ 1 , m ] , [ 1 , n − m ] [1,n],[1,m],[1,n-m] [1,n],[1,m],[1,n−m]中与 a i a_i ai互质的数乘起来即可——当然不是直接暴力乘,发现可以以 a i b i a_i^{b_i} aibi为循环节分组,每一个循环节内的乘积都是一样的,快速幂即可。
之所以讲得如此简略,显然是因为这其实像是数论的内容。
消去乘积
- ∑ i = 0 n ( a i ) ∗ ( b n − i ) = ( a + b n ) \sum_{i=0}^n \binom{a}{i}*\binom{b}{n-i}=\binom{a+b}{n} ∑i=0n(ia)∗(n−ib)=(na+b)
- ∑ i = 0 n ( i a ) ∗ ( n − i b ) = ( n + 1 a + b + 1 ) \sum_{i=0}^n\binom{i}{a}*\binom{n-i}{b}=\binom{n+1}{a+b+1} ∑i=0n(ai)∗(bn−i)=(a+b+1n+1)
挡板问题
- 有 n n n个有序正整数加起来等于 m m m,求方案数?
- 该问题的答案为 ( m − 1 n − 1 ) \binom{m-1}{n-1} (n−1m−1)。
- 如果每一个数有限定最小值 d d d,那么方案数为 ( m − ( d − 1 ) ∗ n − 1 n − 1 ) \binom{m-(d-1)*n-1}{n-1} (n−1m−(d−1)∗n−1)。
定义域的扩展
-
对于组合数 ( n m ) \binom{n}{m} (mn),我们可以扩展到 n n n为实数的情况:
-
( n m ) = Π i = 0 m − 1 ( n − i ) m ! ( n ∈ R , m ∈ N ) \binom{n}{m}=\frac{\Pi_{i=0}^{m-1}(n-i)}{m!}(n\in \R,m\in \N) (mn)=m!Πi=0m−1(n−i)(n∈R,m∈N)
-
该组合数仍然满足二项式定理,意即:
-
( a + b ) n = ∑ i = 0 ∞ a i ∗ b n − i ∗ ( n i ) ( n ∈ R ) (a+b)^n=\sum_{i=0}^\infty a^i*b^{n-i}*\binom{n}{i}(n\in \R) (a+b)n=i=0∑∞ai∗bn−i∗(in)(n∈R)
-
这个时候大家或许会有疑惑,左式 a , b a,b a,b是对称的,但右式 a , b a,b a,b并不是对称的,这是为什么呢?
-
这是因为——想让这个式子有值,就必须让右式是收敛的而非发散的。
-
例如 ( 2 + 1 ) 1.5 (2+1)^{1.5} (2+1)1.5,倘若我们代入 a = 2 , b = 1 a=2,b=1 a=2,b=1,跑一下程序你就会发现右边的式子只会在很大的正数和很大的负数之间左右横跳,只有当 a = 1 , b = 2 a=1,b=2 a=1,b=2时,才可以趋近于 3 1.5 3^{1.5} 31.5。
-
一般情况下,我们发现每增加1,右式不考虑组合数的话就会乘上 a b \frac{a}{b} ba,所以只要让 a b < 1 \frac{a}{b}<1 ba<1就行了。
-
那么这东西有什么用呢?
-
其实要是在数学领域,这东西绝对会有超级多奇奇怪怪的用处,这里就介绍一个和生成函数相关的。
-
比如对于 x + 1 \sqrt{x+1} x+1,我们当然可以
多项式开方,但是我们也可以先用二项式定理展开一下: -
1 + x = ( 1 + x ) 1 2 = ∑ i = 0 ∞ x i ∗ ( 1 2 i ) \sqrt{1+x}=(1+x)^{\frac{1}{2}}=\sum_{i=0}^\infty x^i*\binom{\frac{1}{2}}{i} 1+x=(1+x)21=i=0∑∞xi∗(i21)
-
这样子就可快速求出某一项的系数了。
生成函数形式
-
由于组合数有两个变量,所以其生成函数一般为二元生成函数:
-
我们需要定义一个生成函数 F F F使得 [ x i y j ] F ( x , y ) = ( i j ) [x^iy^j]F(x,y)=\binom{i}{j} [xiyj]F(x,y)=(ji)。
-
发现可以直接展开:
-
F ( x , y ) = ∑ i = 0 ∑ j = 0 ( i j ) x i y j = ∑ i = 0 x i ∗ ( y + 1 ) i = 1 1 − x ∗ ( y + 1 ) \begin{aligned} F(x,y)&=\sum_{i=0}\sum_{j=0}\binom{i}{j}x^iy^j\\ &=\sum_{i=0}x^i*(y+1)^i\\ &=\frac{1}{1-x*(y+1)} \end{aligned} F(x,y)=i=0∑j=0∑(ji)xiyj=i=0∑xi∗(y+1)i=1−x∗(y+1)1
-
那么这个有什么用呢?我们来看下面这个式子:
-
∑ i = 0 n ( n + i 2 ∗ i ) \sum_{i=0}^n\binom{n+i}{2*i} ∑i=0n(2∗in+i)
-
看起来似乎没有什么直接的方法算出这个式子的值。
-
但是我们发现这个组合数有特定的线性关系,这个式子中的每一个组合数 ( a b ) \binom{a}{b} (ba),都满足 2 ∗ a − b = 2 ∗ n 2*a-b=2*n 2∗a−b=2∗n。
-
考虑如何用生成函数表示这种关系,一种直观的方法是将二元生成函数变为一元生成函数,即将 y = x − 1 2 y=x^{-\frac{1}{2}} y=x−21代入,那么 x i y j = x i ( x − 1 2 ) j = x i − j 2 x^iy^j=x^i(x^{-\frac{1}{2}})^j=x^{i-\frac{j}{2}} xiyj=xi(x−21)j=xi−2j,只要满足 i − j 2 = n i-\frac{j}{2}=n i−2j=n即可,所以只需要求出这个生成函数 x n x^n xn的系数。
-
代入后得到的生成函数为:
-
1 1 − x ∗ ( x − 1 2 + 1 ) = 1 1 − x − x \frac{1}{1-x*(x^{-\frac{1}{2}}+1)}=\frac{1}{1-\sqrt{x}-x} 1−x∗(x−21+1)1=1−x−x1
-
发现它和斐波那契数列的生成函数神似,实际上可以得出 ∑ i = 0 n ( n + i 2 ∗ i ) = F 2 n + 1 \sum_{i=0}^n\binom{n+i}{2*i}=F_{2n+1} ∑i=0n(2∗in+i)=F2n+1,其中 F F F表示斐波那契数列。
-
实际上如果从组合意义角度去考虑斐波那契,设 G n G_n Gn表示有一排 n n n个格子,往里面放球,需要每个球之间要么相邻,要么只有一个空格子,现在已经确定 n n n号会放球,求剩下格子放球的方案数,发现其满足递推式 G i = G i − 1 + G i − 2 G_i=G_{i-1}+G_{i-2} Gi=Gi−1+Gi−2,但需要平移 G i = F i + 1 G_i=F_{i+1} Gi=Fi+1。
-
与此同时,如果我们用组合数来求解方案数,由于空格子之间不能相邻,所以可以考虑枚举空格子的个数 k k k,运用挡板问题可以发现方案数为 ( n − k k ) \binom{n-k}{k} (kn−k),那么总方案数为 G n = ∑ i = 0 n ( n − i i ) G_n=\sum_{i=0}^n\binom{n-i}{i} Gn=∑i=0n(in−i)。
-
所以 F 2 ∗ n + 1 = G 2 ∗ n = ∑ i = 0 2 ∗ n ( 2 ∗ n − i i ) = ∑ i = 0 2 ∗ n ( n + ( n − i ) 2 ∗ ( n − i ) ) = ∑ i = 0 n ( n + i 2 ∗ i ) F_{2*n+1}=G_{2*n}=\sum_{i=0}^{2*n}\binom{2*n-i}{i}=\sum_{i=0}^{2*n}\binom{n+(n-i)}{2*(n-i)}=\sum_{i=0}^{n}\binom{n+i}{2*i} F2∗n+1=G2∗n=∑i=02∗n(i2∗n−i)=∑i=02∗n(2∗(n−i)n+(n−i))=∑i=0n(2∗in+i)。
-
倘若正推的话,显然组合意义的思维难度比生成函数高,所以遇到复杂的组合问题常常可以用生成函数求解。