组合原理

加法原理

用第一种方法可以写完这篇文章。
用第二种方法可以写完这篇文章。

用第n种方法可以写完这篇文章。

想要写完文章,共有多少种方式呢?
显然是n种。

这表明,从状态x转移到状态y(从没写完文章到写完文章),共有n种转移,就意味着有n种方法可以从状态x转移到状态y:

共有m种可能性

乘法原理

从状态x1转移到状态x2,有m1种方法。
从状态x2转移到状态x3,有m2种方法。

从状态xn-1转移到状态xn,有mn-1种方法。

共有 ∏ i = 1 n − 1 m i \overset{n-1}{\underset{i=1}{\prod}}m_i i=1∏​n−1​mi​种方法。

共有 ∏ i = 1 n − 1 m i \overset{n-1}{\underset{i=1}{\prod}}m_i i=1∏​n−1​mi​种可能性。

阶乘

从一个盒子里取出n个不同颜色的小球。把小球按照取出的顺序排好,总共有多少种可能的序列?

假如有{A,B,C}三种颜色的小球,可以画树状图:

3×2×1,共有6种情况。

事实上,这对应三种递进的状态:
状态 1 ( 压根没选 ) − > { 选颜色 A 选颜色 B 选颜色 C 状态1(压根没选)->\left\{\begin{matrix} 选颜色A\\ 选颜色B\\ 选颜色C \end{matrix}\right. 状态1(压根没选)−>⎩ ⎨ ⎧​选颜色A选颜色B选颜色C​
状态 2 ( 选了一个颜色 ) − > { 选剩下的一种颜色 选剩下的另一种颜色 状态2(选了一个颜色)->\left\{\begin{matrix} 选剩下的一种颜色\\ 选剩下的另一种颜色 \end{matrix}\right. 状态2(选了一个颜色)−>{选剩下的一种颜色选剩下的另一种颜色​
状态 3 ( 选了两种颜色 ) − > { 选剩下的最后一种颜色 状态3(选了两种颜色)->\{选剩下的最后一种颜色 状态3(选了两种颜色)−>{选剩下的最后一种颜色

因此从一个盒子里取出n个不同颜色的小球。把小球按照取出的顺序排好,可能的序列数是 n × ( n − 1 ) × ( n − 2 ) × . . . × 2 × 1 = ∏ i = 1 n i n\times (n-1)\times(n-2)\times...\times 2\times1=\prod_{i=1}^ni n×(n−1)×(n−2)×...×2×1=∏i=1n​i

定义 ∏ i = 1 n \prod_{i=1}^n ∏i=1n​为 n ! n! n!,
也就是说,n个不同元素任意排列,可能的方案数有 n ! n! n!种。

0个元素任意排列,可能的方案只有一种,就是排不了。即 0 ! = 1 0!=1 0!=1

排列

关于集合S,把集合里的元素取出,得到的一个有序序列,这个序列称为S的一个排列。

定义 P n m = A n m P^m_n=A^m_n Pnm​=Anm​表示从 n n n个不同元素中,取出 m m m个元素,按照取出的顺序排好,可能得到的排列种类数。
A n m A_n^m Anm​称为排列数(线排列)。

显然有: A n m = n ! ( n − m ) ! A_n^m=\frac {n!}{(n-m)!} Anm​=(n−m)!n!​

考虑首先枚举全排列,然后去除重复的情况:
举个例子:共有五个元素,用斜体表示我们选出的2个元素,考虑顺序:

假设取出 A , B A,B A,B:
{ A , B A,B A,B,C,D,E}
{ A , B A,B A,B,C,E,D}
{ A , B A,B A,B,D,C,E}
{ A , B A,B A,B,D,E,C}
{ A , B A,B A,B,E,C,D}
{ A , B A,B A,B,E,D,C}
对于选出 A , B A,B A,B这种情况来说,就算重了 ( n − m ) ! (n-m)! (n−m)!次。

假设取出 B , A B,A B,A:
{ B , A B,A B,A,C,D,E}
{ B , A B,A B,A,C,E,D}
{ B , A B,A B,A,D,C,E}
{ B , A B,A B,A,D,E,C}
{ B , A B,A B,A,E,C,D}
{ B , A B,A B,A,E,D,C}
对于选出 B , A B,A B,A这种情况来说,就算重了 ( n − m ) ! (n-m)! (n−m)!次。

假设取出 A , C A,C A,C:
{ A , C A,C A,C,B,D,E}
{ A , C A,C A,C,B,E,D}
{ A , C A,C A,C,D,B,E}
{ A , C A,C A,C,D,E,B}
{ A , C A,C A,C,E,B,D}
{ A , C A,C A,C,E,D,B}
对于选出 A , C A,C A,C这种情况来说,就算重了 ( n − m ) ! (n-m)! (n−m)!次。

同理,在 n ! n! n!种全排列中,每一种取出方式都重复计算了 ( n − m ) ! (n-m)! (n−m)!次,因此最终的种类数是 A n m = n ! ( n − m ) ! A_n^m=\frac {n!}{(n-m)!} Anm​=(n−m)!n!​

组合

定义一个集合S称为关于S的一个组合,组合无关于顺序。

定义 C n m = ( m n ) C_n^m=(^{\,n}_m) Cnm​=(mn​),表示从n个不同元素中取出m个元素构成一个组合,可能形成的组合的种类数, ( m n ) (^{\,n}_m) (mn​)称为组合数。

显然有: ( m n ) = n ! m ! ( n − m ) ! (^{n}_m)=\frac {n!}{m!(n-m)!} (mn​)=m!(n−m)!n!​

这是因为,首先我们考虑从n个不同元素中取出m个,考虑顺序的方案数,就是排列数 A n m A_n^m Anm​,然后我们考虑,每一种组合的全排列都算作全排列的个数次贡献,每种组合都多做了 m ! m! m!倍的贡献。就比如上面的例子,{ A , B A,B A,B}和{ B , A B,A B,A}是一种组合,但却被算了两次,这是由于,{ A , B A,B A,B}的每个排列都被计算了一次。因此组合数 ( m n ) = A n m m ! = n ! m ! ( n − m ) ! (^{n}_m)=\frac {A_n^m}{m!}=\frac {n!}{m!(n-m)!} (mn​)=m!Anm​​=m!(n−m)!n!​

圆排列

定义 Q n n Q_n^n Qnn​表示n个不同元素围成一圈,可能形成的环的种类数,称为圆排列数(环排列数)。
考虑每一个圆排列从任意位置断开都可以得到对应的线排列,因此 n ⋅ Q n n = A n n n\cdot Q_n^n=A^n_n n⋅Qnn​=Ann​,则有: Q n n = A n n n = ( n − 1 ) ! Q_n^n=\frac {A^n_n} n=(n-1)! Qnn​=nAnn​​=(n−1)!

定义 Q n m Q_n^m Qnm​表示n个不同元素中选出m个组成一个环,得到的圆排列数。

显然有: Q n m = ( m n ) ⋅ Q m m = n ! m ( n − m ) ! Q_n^m=(^n_m)\cdot Q_m^m=\frac {n!} {m(n-m)!} Qnm​=(mn​)⋅Qmm​=m(n−m)!n!​
这表示,先从n的不同元素中选出m个元素,再求出m个元素的圆排列数。

错位排列

给定一个去重的序列,如果这个序列的一个排列,满足任意一个元素都不处于原本序列的位置上,那么这个排列称为序列的一个错位排列。
简单而言,序列{1,2,…,n}的一个排列,如果满足 ∀ \forall ∀ai≠i,则称这个排列是关于n的一个错位排列。

这样定义 D n D_n Dn​表示有多少个关于n的错位排列。 D n D_n Dn​称为错位排列数。

显然有: D 1 = 0 , D 2 = 1 D_1=0,D_2=1 D1​=0,D2​=1

那么有错位排列的递推公式: 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​)
考虑如何通过一次操作,就得到关于n的错排:

  1. 前n-1个数构成一个错排,只需要把任意一个数放在 a n a_n an​的位置,把n放在那个空出来的位置上。放置n有 n − 1 n-1 n−1种方案。
  2. 前n-1个数中,仅有一个数满足 a i = i a_i=i ai​=i,只需要把 n n n放在 a i a_i ai​的位置上,然后把 i i i放在 a n a_n an​的位置上就可以了。这样的i有n-1种可能。

事实上,错排还有二项式反演的计算公式:
D n = ∑ i = 0 n ( − 1 ) n − i ( i n ) i ! D_n=\overset{n}{\underset{i=0}\sum}(-1)^{n-i}\left(^n_i\right)i! Dn​=i=0∑​n​(−1)n−i(in​)i!

这个公式在二项式反演中给出证明,事实上,也可以通过把递推式带入的方法得到通项公式。

事实上,错排公式还可以通过多项式模拟得到,这里不讨论。

多重组合数

*这里说的多重组合数,不是“多重集组合数”。
将n个不同元素划分为m个集合,使得第i个集合的元素数量为mi个,有多少种划分的可能数记作: ( m 1 , m 2 , . . . , m m n ) \left(^{\;\;\;\;\;\;\;\;n}_{m_1,m_2,...,m_m}\right) (m1​,m2​,...,mm​n​)

那么重数为 ∏ i m i ! \underset{i}\prod m_i! i∏​mi​!,因此: ( m 1 , m 2 , . . . , m m n ) = n ! ∏ i m i ! \left(^{\;\;\;\;\;\;\;\;n}_{m_1,m_2,...,m_m}\right)=\frac{n!}{\underset{i}\prod m_i!} (m1​,m2​,...,mm​n​)=i∏​mi​!n!​

多重组合数与多项式定理有关。

组合公式与变换技巧

排列数,圆排列数,错位排列数不常变换。

组合数公式

根据定义,显然有: ( m n ) = ( n − m n ) (^n_m)=(^n_{n-m}) (mn​)=(n−mn​)

公式1:递推式

( m n ) = ( m n − 1 ) + ( m − 1 n − 1 ) (^n_m)=(^{n-1}_m)+(^{n-1}_{m-1}) (mn​)=(mn−1​)+(m−1n−1​)
考虑第一个元素选或者不选,如果不选,要在接下里的n-1个元素中选出m个。如果选,在接下来的n-1个元素中只需要选出m-1个。

公式2:分离式

分离式正变换

( k n ) ( m k ) = ( m n ) ( k − m n − m ) \left(^n_k\right)\left(^k_m\right)=\left(^n_m\right)\left(^{n-m}_{k-m}\right) (kn​)(mk​)=(mn​)(k−mn−m​)
考虑先从n中选k个,再从k中选m个。等价于先从n中选m个,再从剩下的n-m中选出k-m个(也就是说,从n中选出m个的,有 ( k − m n − m ) \left(^{n-m}_{k-m}\right) (k−mn−m​)种情况)。

分离式常用于斯特林反演。

在组合代换中,分离式往往从右边推向左边:
( m n ) ( k − m n − m ) = ( k n ) ( m k ) \left(^n_m\right)\left(^{n-m}_{k-m}\right)=\left(^n_k\right)\left(^k_m\right) (mn​)(k−mn−m​)=(kn​)(mk​)

分离式逆变换

( m n ) ( i n − m ) = ( m + i n ) ( i m + i ) (^n_m)(^{n-m}_i)=(^n_{m+i})(^{m+i}_i) (mn​)(in−m​)=(m+in​)(im+i​)

分离式逆变换是组合代换的重要公式。

证明一下:

( m n ) ( i n − m ) (^n_m)(^{n-m}_i) (mn​)(in−m​),设 i = k − m i=k-m i=k−m。
则: ( m n ) ( i n − m ) = ( m n ) ( k − m n − m ) = ( k n ) ( m k ) = ( m + i n ) ( m m + i ) (^n_m)(^{n-m}_i)=(^n_m)(^{n-m}_{k-m})=(^n_k)(^k_m)=(^n_{m+i})(^{m+i}_{m}) (mn​)(in−m​)=(mn​)(k−mn−m​)=(kn​)(mk​)=(m+in​)(mm+i​)

QED.

公式3:组合恒等式

k ( k n ) = n ( k − 1 n − 1 ) k(^n_k)=n(^{n-1}_{k-1}) k(kn​)=n(k−1n−1​)
留作习题,读者自证不难。

组合恒等式也可以用于斯特林反演,但不常用。

这个公式的高维形式(即 k p k^p kp)与斯特林反演有关。

推论式

( k n − 1 ) − ( k − 1 n − 1 ) = n − 2 k n ( k n ) (^{n-1}_k)-(^{n-1}_{k-1})=\frac {n-2k}{n}(^n_k) (kn−1​)−(k−1n−1​)=nn−2k​(kn​)
没什么用。

证明一下:
( k n − 1 ) − ( k − 1 n − 1 ) = n − 2 k n ( k n ) (^{n-1}_k)-(^{n-1}_{k-1})=\frac {n-2k}{n}(^n_k) (kn−1​)−(k−1n−1​)=nn−2k​(kn​)

首先考虑把n乘到左边:
n ( k n − 1 ) − n ( k − 1 n − 1 ) = ( n − 2 k ) ( k n ) n(^{n-1}_k)-n(^{n-1}_{k-1})=(n-2k)(^n_k) n(kn−1​)−n(k−1n−1​)=(n−2k)(kn​)
n ( k n − 1 ) − n ( k − 1 n − 1 ) = n ( k n ) − 2 k ( k n ) n(^{n-1}_k)-n(^{n-1}_{k-1})=n(^n_k)-2k(^n_k) n(kn−1​)−n(k−1n−1​)=n(kn​)−2k(kn​)

左边有点像递推式,但是符号不对,考虑把右边带入递推式,能消掉一项:
n ( k n − 1 ) − n ( k − 1 n − 1 ) = n ( ( k n − 1 ) + ( k − 1 n − 1 ) ) − 2 k ( k n ) n(^{n-1}_k)-n(^{n-1}_{k-1})=n\left((^{n-1}_k)+(^{n-1}_{k-1})\right)-2k(^n_k) n(kn−1​)−n(k−1n−1​)=n((kn−1​)+(k−1n−1​))−2k(kn​)
n ( k n − 1 ) − n ( k − 1 n − 1 ) = n ( k n − 1 ) + n ( k − 1 n − 1 ) − 2 k ( k n ) n(^{n-1}_k)-n(^{n-1}_{k-1})=n(^{n-1}_k)+n(^{n-1}_{k-1})-2k(^n_k) n(kn−1​)−n(k−1n−1​)=n(kn−1​)+n(k−1n−1​)−2k(kn​)
− n ( k − 1 n − 1 ) = n ( k − 1 n − 1 ) − 2 k ( k n ) -n(^{n-1}_{k-1})=n(^{n-1}_{k-1})-2k(^n_k) −n(k−1n−1​)=n(k−1n−1​)−2k(kn​)
2 k ( k n ) = 2 n ( k − 1 n − 1 ) 2k(^n_k)=2n(^{n-1}_{k-1}) 2k(kn​)=2n(k−1n−1​)

这显然就是组合恒等式:
k ( k n ) = n ( k − 1 n − 1 ) k(^n_k)=n(^{n-1}_{k-1}) k(kn​)=n(k−1n−1​)

QED.

公式4:组合数求和

对于组合数 ( B A ) (^A_B) (BA​),我们说 A A A是顶项, B B B是底项。

顶项为常数

∑ i = 0 n ( i n ) = 2 n \overset{n}{\underset{i=0}\sum}(^n_i)=2^n i=0∑​n​(in​)=2n
左式取遍了n个元素的集合的所有子集。

也可以用二项式定理证明。

对于 ∑ i = 0 m ( i n ) \overset{m}{\underset{i=0}\sum}(^n_i) i=0∑​m​(in​),我暂时还没有找到一个比较好的方法求和,唐绍轩和黄楚宇说似乎不太好求。

底项为常数(朱世杰恒等式)

∑ i = 0 n ( m i ) = ( m + 1 n + 1 ) \overset{n}{\underset{i=0}\sum}(^i_m)=\left(^{n+1}_{m+1}\right) i=0∑​n​(mi​)=(m+1n+1​)

证明一下:
首先考虑把级数展开:
左 = ∑ i = 0 n ( m i ) = ( m 0 ) + ( m 1 ) + ( m 2 ) + . . . + ( m n − 2 ) + ( m n − 1 ) + ( m n ) 左=\overset{n}{\underset{i=0}\sum}(^i_m)=(^0_m)+(^1_m)+(^2_m)+...+(^{n-2}_m)+(^{n-1}_m)+(^n_m) 左=i=0∑​n​(mi​)=(m0​)+(m1​)+(m2​)+...+(mn−2​)+(mn−1​)+(mn​)

考虑到右边的底项比左边大,可以想办法降下来,右侧可以套进递推式:
右 = ( m + 1 n + 1 ) = ( m + 1 n ) + ( m n ) 右=\left(^{n+1}_{m+1}\right)=(^n_{m+1})+(^n_m) 右=(m+1n+1​)=(m+1n​)+(mn​)

再套递推式:
右 = ( m + 1 n + 1 ) = ( m + 1 n − 1 ) + ( m n − 1 ) + ( m n ) 右=\left(^{n+1}_{m+1}\right)=(^{n-1}_{m+1})+(^{n-1}_m)+(^n_m) 右=(m+1n+1​)=(m+1n−1​)+(mn−1​)+(mn​)

对比一下左边:
左 = ( m 0 ) + ( m 1 ) + ( m 2 ) + . . . + ( m n − 2 ) + ( m n − 1 ) + ( m n ) 左=(^0_m)+(^1_m)+(^2_m)+...+(^{n-2}_m)+(^{n-1}_m)+(^n_m) 左=(m0​)+(m1​)+(m2​)+...+(mn−2​)+(mn−1​)+(mn​)
右 = ( m + 1 n − 1 ) + ( m n − 1 ) + ( m n ) 右=(^{n-1}_{m+1})+\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;\;(^{n-1}_m)+(^n_m) 右=(m+1n−1​)+(mn−1​)+(mn​)

这样就有一部分可以约掉了(这里先保留)。

然后我们重复套递推式:
右 = ( m + 1 n − k ) + ( m n − k ) + . . . + ( m n − 2 ) + ( m n − 1 ) + ( m n ) 右=(^{n-k}_{m+1})+(^{n-k}_m)+...+(^{n-2}_m)+(^{n-1}_m)+(^n_m) 右=(m+1n−k​)+(mn−k​)+...+(mn−2​)+(mn−1​)+(mn​)

令k=n,对比一下:
左 = ( m 0 ) + ( m 1 ) + ( m 2 ) + . . . + ( m n − 2 ) + ( m n − 1 ) + ( m n ) 左=\;\;\;\;\;\;\;\;\;\;\;\;\;(^0_m)+(^1_m)+(^2_m)+...+(^{n-2}_m)+(^{n-1}_m)+(^n_m) 左=(m0​)+(m1​)+(m2​)+...+(mn−2​)+(mn−1​)+(mn​)
右 = ( m + 1 0 ) + ( m 0 ) + ( m 1 ) + ( m 2 ) + . . . + ( m n − 2 ) + ( m n − 1 ) + ( m n ) 右=(^0_{m+1})+(^0_m)+(^1_m)+(^2_m)+...+(^{n-2}_m)+(^{n-1}_m)+(^n_m) 右=(m+10​)+(m0​)+(m1​)+(m2​)+...+(mn−2​)+(mn−1​)+(mn​)

显然 ( m + 1 0 ) = 0 (^0_{m+1})=0 (m+10​)=0喽,所以左边=右边。

QED.

推论

∑ i = k n ( m i ) = ∑ i = 0 n ( m i ) − ∑ i = 0 k − 1 ( m i ) = ( m + 1 n + 1 ) − ( m + 1 k ) \overset{n}{\underset{i=k}\sum}(^i_m)=\overset{n}{\underset{i=0}\sum}(^i_m)-\overset{k-1}{\underset{i=0}\sum}(^i_m)=\left(^{n+1}_{m+1}\right)-\left(^{k}_{m+1}\right) i=k∑​n​(mi​)=i=0∑​n​(mi​)−i=0∑​k−1​(mi​)=(m+1n+1​)−(m+1k​)

组合数求和难以直接优化时间复杂度,往往用于变换的步骤。

示例:
∑ i = 0 n ( i a + i ) = ∑ i = 0 n ( a a + i ) = ∑ i = a n + a ( a i ) \overset{n}{\underset{i=0}\sum}(^{a+i}_i)=\overset{n}{\underset{i=0}\sum}(^{a+i}_a)=\overset{n+a}{\underset{i=a}\sum}(^{i}_a) i=0∑​n​(ia+i​)=i=0∑​n​(aa+i​)=i=a∑​n+a​(ai​)
设 n + a = N n+a=N n+a=N, 原式 = ∑ i = a N ( a i ) 原式=\overset{N}{\underset{i=a}\sum}(^{i}_a) 原式=i=a∑​N​(ai​),这样就很容易求了。

如果只有底项上有常量,可以直接套朱世杰恒等式。

刚才的示例启示我们,如果组合数的上下都含有变量,可以想办法先把底项搞成常量,再对顶项换元,转化成求 ∑ ( m i ) \sum(^i_m) ∑(mi​)的形式。

但是如果顶项上只有常量,就不太好办了。

公式5:组合数卷积

对于一些组合数,我们可以分成两部枚举计算。

(底项为变量)范德蒙德卷积公式

从固定的两个组合中选取的总数是不变的,取遍所有可能,做法就是把两个组合数拍成一个 ( i n ) ( k − i m ) − > ( k n + m ) (_i^n)(^m_{k-i})->(^{n+m}_k) (in​)(k−im​)−>(kn+m​):

∑ i = 0 n ( i n ) ( k − i m ) = ( k n + m ) \overset{n}{\underset{i=0}\sum}(^n_i)(^m_{k-i})=(^{n+m}_k) i=0∑​n​(in​)(k−im​)=(kn+m​)

先从n中选i个,再从m中选k-i个,并且 i ∈ [ 0 , n ] i \in [0,n] i∈[0,n],这意味着取遍了关于n+m的组合的所有可能,等价于从n+m中选出k个。

范德蒙德卷积公式用于特定组合数的时间复杂度优化:例题

范德蒙德卷积公式还有两种常见用法:

  1. 优化形如 ∑ i = 0 n ( i n ) ( i m ) \overset{n}{\underset{i=0}\sum}(^n_i)(^m_{i}) i=0∑​n​(in​)(im​)的组合数求和问题: ∑ i = 0 n ( i n ) ( i m ) = ∑ i = 0 n ( i n ) ( m − i m ) = ( m n + m ) \overset{n}{\underset{i=0}\sum}(^n_i)(^m_{i})=\overset{n}{\underset{i=0}\sum}(^n_i)(^m_{m-i})=(^{n+m}_m) i=0∑​n​(in​)(im​)=i=0∑​n​(in​)(m−im​)=(mn+m​)
  2. 对于形如 ( k x + y ) \left(^{x+y}_k\right) (kx+y​)的式子,可以回套范德蒙德卷积公式,做组合变换。

顶项为变量:

拍起来之后要上下两项要加1:

∑ i = 0 n ( x x + n − i ) ( y y + i ) = ( x + y + 1 x + y + n + 1 ) \overset{n}{\underset{i=0}\sum}\left(^{x+n-i}_{x}\right)\left(^{y+i}_{y}\right)=\left(^{x+y+n+1}_{x+y+1}\right) i=0∑​n​(xx+n−i​)(yy+i​)=(x+y+1x+y+n+1​)

一种显然的想法是,有 x + y + n x+y+n x+y+n个元素,取 x + y x+y x+y个元素,枚举一个隔板,使得左边选x个,右边选y个,就相当于直接取 x + y x+y x+y个,那么答案就是 ( x + y x + y + n ) \left(^{x+y+n}_{x+y}\right) (x+yx+y+n​),但是模拟一下就会发现这是错的,因为隔板不必要选(也选不了),所以这样就可能统计到两种相同的情况,而 ( x + y x + y + n ) \left(^{x+y+n}_{x+y}\right) (x+yx+y+n​)不会统计到相同的情况,所以会比实际答案小:

所以我们必须强制选一个位置,考虑共有 x + y + n + 1 x+y+n+1 x+y+n+1个元素,从中取 x + y + 1 x+y+1 x+y+1个。这等价于,枚举一个位置,强制这个位置必选,这个元素前面选x个元素,后面选y个元素,这样就不会算重了,也即 ( x + y + 1 x + y + n + 1 ) \left(^{x+y+n+1}_{x+y+1}\right) (x+y+1x+y+n+1​)。

QED.

事实上,由于相似的理由,在相当多的组合计数题中,都必须强制指定一个位置必选,就比如上面范德蒙德卷积公式的例题。
这种限制方法的精髓在于,保证目前枚举的情况,一定属于之前枚举时的不合法情况,这样才保证不会重复。由于枚举,因此不会漏解。

这个公式也可以用于回套,做组合变换。

公式6:李善兰公式

( x n ) 2 = ∑ i = 0 x ( i x ) 2 ( 2 x n + i ) (^n_x)^2=\overset{x}{\underset{i=0}\sum}(^x_i)^2(^{n+i}_{2x}) (xn​)2=i=0∑​x​(ix​)2(2xn+i​)

令 n = n + x , i = x − i , x 记作 k n=n+x,i=x-i,x记作k n=n+x,i=x−i,x记作k,即得常见的李善兰公式: ( k n + k ) 2 = ∑ i = 0 k ( i k ) 2 ( 2 k n + 2 k − i ) (^{n+k}_k)^2=\overset{k}{\underset{i=0}\sum}(^k_i)^2(^{n+2k-i}_{2k}) (kn+k​)2=i=0∑​k​(ik​)2(2kn+2k−i​)

可以从组合意义证明一下:
李善兰公式其实是根据这个公式得到的(设 x ≤ y x\leq y x≤y):
( x n ) ( y n ) = ∑ i = 0 x ( i x ) ( i y ) ( x + y n + i ) (^n_x)(^n_y)=\overset{x}{\underset{i=0}\sum}(^x_i)(^y_i)(^{n+i}_{x+y}) (xn​)(yn​)=i=0∑​x​(ix​)(iy​)(x+yn+i​)

组合意义

这个公式的组合意义很明显,左边表示先从n个数中选x个数,再从n个数中选y个数。右边表示枚举选的x个数和y个数中有多少个是共同的,那就相当于先从n+i个数中选出x+y个数,再从x个数中选出i个数,y个数中选出i个数,使得这2i个数是共同的i个数。

从组合代换也可以证明李善兰公式,证明较繁。

公式7

( n 2 n ) = ∑ i = 0 n ( i n ) 2 (^{2n}_n)=\overset{n}{\underset{i=0}\sum}(^n_i)^2 (n2n​)=i=0∑​n​(in​)2

这是范德蒙德卷积的一种特殊形式。也可以构造多项式证明,作者不会。

多重组合数公式

定义:

多重组合数递推式

考虑第一个元素应该被分入哪个集合。

广义乘法原理

若从状态xi转移到状态xi+1,有mi种方案,其中第j种方案的权值是wi。定义从状态x1转移到状态xn的权值为每一次选择方案的权值之积,则总权值等于: ∏ i = 1 n − 1 ∑ m i j = 1 w j \overset{n-1}{\underset{i=1}\prod}\underset{j=1}{\overset{m_i}\sum} w_j i=1∏​n−1​j=1∑mi​​​wj​

证明一下:
我们假设有这样的状态与转移:

也就是说,x1->x2对应的权值为{3,7,8},x2->x3对应的权值为{2,1}。
从每一集合内任选一种,做乘积。再把所有可能性加和,显然符合乘法的形式:
ans=(3+7+8)×(2+1)

推理过程显然具有普遍性。
QED.

后记

于是皆大欢喜。

组合意义,排列组合基础相关推荐

  1. c语言中组合函数,排列组合c怎么算 公式是什么

    排列有两种定义,但计算方法只有一种,凡是符合这两种定义的都用这种方法计算.定义的前提条件是m≦n,m与n均为自然数.下面介绍排列组合c的计算方法及公式,供参考. 排列组合中A和C怎么算 排列A(n,m ...

  2. 统计学练习题——组合,排列组合

    统计学习题 组合 组合的基本公式:C(n,m)的算法=n!/[m!(n-m)!] 1.26个字母随机取4个,抽出不放回,有多少种可能? C(26,4) = 26!/(4!*(22!)) 第一步先约掉2 ...

  3. python生成排列组合_Python 排列组合生成

    zckun:老哥们, 请教一个问题, 是关于排列组合的, 前几天和老哥们讨论了一下, 能是能解决, 但感觉不太方便 看一个简单的例子应该就明白了. to 目前是我这样做的, 用了一个模版 templa ...

  4. matlab 重复排列组合,MATLAB 排列组合问题

    毕设ing, 最近每天除了看论文就是matlab仿真. MATLAB编程强调"vectorization'',对矩阵进行操作(毕竟人家名字就叫Mat Lab,矩阵的实验室) 对于排列组合问题 ...

  5. java 实现组合_排列组合算法(JAVA实现)

    组合算法实现 从m个数里面取n个数的算法.最容易理解的就是递归,但是其效率太低. 实现方法一: // 组合算法 // 本程序的思路是开一个数组,其下标表示1到n个数,数组元素的值为1表示其下标 //  ...

  6. python输入一个字符串、输出他的所以组合_Swift - 排列组合之全排列 (输入一个字符串,输出该字符串包含的字符的所有组合)...

    因为项目需求,要用到全排列,在此记录下来.全排列公式: f(n) = n! (n>=0) 此demo为,输入一个字符串,遍历字符串中每个字符,并组成一个新的字符串.通过递归算法,得到所有字符组成 ...

  7. 组合数学(排列组合,容斥原理,数论定理)

    组合数学的学习 排列组合 一.排列组合基础 二.排列组合练习题 容斥原理 定理学习 例题练习 例题1: [ 1 , n ] [1,n] [1,n] 中有多少个数能被 x 或 y 整除 例题2: [ 1 ...

  8. 排列组合、古典概型、几何概型与伯努利概型

    排列组合 (1)排列组合公式 从mmm个人中挑出nnn个人进行排列的可能数:Pmn=m!(m−n)!P_m^n = \frac{m!}{(m-n)!}Pmn​=(m−n)!m!​从mmm个人中挑出nn ...

  9. TIA博途SCL编程学习21_4个数字中的3个数字的排列组合

    从四个数字中选出三个,一共有多少组合?不重复的 排列组合问题.从四个数字中选出三个,一共有C(4,3)=4*3*2/3*2*1=4种组合. 排列组合问题联系实际且生动有趣,但题型多样,思路灵活,因此解 ...

  10. 数列的组合及排列方式java_java数组排列组合

    ⑥ 对于正面考虑太复杂的问题,可以考虑反面. ⑦ 对于一些排列数与组合数的问题,需要构造模型. 典例分析排列数组合数的简单计算 [例1] 对于满足 n ≥ 13 的正...... Java 实现排列组 ...

最新文章

  1. php程序监听node.js程序和go程序
  2. 模板网站建设过程中需要注意哪些细节问题?
  3. 【专题介绍】视频内容生产与消费创新(Part2)
  4. java 无法加载资源,JavaScript:无法加载资源:服务器响应状态为404(未找到)
  5. sybase 中可以对现有的表结构进行增加
  6. HTTP协议详解(经典)
  7. 关于EditPlus3 取消备份后再重新打开 备份设置还原到默认状态的问题
  8. SpringBoot单元测试的@RunWith与@SpringBootTest注解
  9. 如何快速搭建一个像“天猫精灵”的智能语音助手?
  10. 四足机器人发展史及机器人盘点
  11. 虹科Automation softPLC | 虹科KPA MoDK运行环境与搭建步骤(2)——MoDK运行环境搭建
  12. 【Linux 内核 内存管理】物理分配页 ⑧ ( __alloc_pages_slowpath 慢速路径调用函数源码分析 | 获取首选内存区域 | 异步回收内存页 | 最低水线也分配 | 直接分配 )
  13. Python异步任务模块之-celery
  14. 使用 eMMC 闪存设备的磨损估计
  15. 操作系统重要概念——虚拟性
  16. 【资源共享】好用的视觉软件Adaptive Vision Studio
  17. Jupyter Notebook 如何安装 + 使用?【审核5次重磅发布】
  18. mete40升级鸿蒙os的机型,首批升级鸿蒙OS系统的机型曝光!华为Mate40首先更新
  19. mybatisPlus中 批量删除
  20. Cisco命令中login和login local的区别

热门文章

  1. Yahoo! 用户密码泄漏安全启示录
  2. mysql 字段移动平均值_MYSQL简单移动平均值计算
  3. 【qt】windows下本地文件的标准url格式
  4. Detour工具包使用
  5. 牛客练习赛63 F 牛牛的树行棋 (SG函数+树差分)
  6. vSAN推荐的IO控制器的配置方式
  7. php strftime 毫秒,php strftime函数获取日期时间(switch用法)
  8. 摘录qq的第二封信,我觉得还是挺客观的
  9. 神经辐射场NeRF之Instant-ngp环境搭建与应用
  10. 小程序文档整理之 -- 场景值