组合原理
加法原理
用第一种方法可以写完这篇文章。
用第二种方法可以写完这篇文章。
…
用第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−1mi种方法。
共有
∏
i
=
1
n
−
1
m
i
\overset{n-1}{\underset{i=1}{\prod}}m_i
i=1∏n−1mi种可能性。
阶乘
从一个盒子里取出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=1ni
定义
∏
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的一个排列。
定义
n
m
‾
=
P
n
m
=
A
n
m
n^{\underline m}=P^m_n=A^m_n
nm=Pnm=Anm表示从
n
n
n个不同元素中,取出
m
m
m个元素,按照取出的顺序排好,可能得到的排列种类数。
n
m
‾
n^{\underline m}
nm称为排列数(线排列)。
显然有: n m ‾ = n ! ( n − m ) ! n^{\underline m}=\frac {n!}{(n-m)!} nm=(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)!次,因此最终的种类数是 n m ‾ = n ! ( n − m ) ! n^{\underline m}=\frac {n!}{(n-m)!} nm=(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个,考虑顺序的方案数,就是排列数 n m ‾ n^{\underline m} nm,然后我们考虑,每一种组合的全排列都算作全排列的个数次贡献,每种组合都多做了 m ! m! m!倍的贡献。就比如上面的例子,{ A , B A,B A,B}和{ B , A B,A B,A}是一种组合,但却被算了两次,这是由于,{ A , B A,B A,B}的每个排列都被计算了一次。因此组合数 ( m n ) = n m ‾ m ! = n ! m ! ( n − m ) ! (^{n}_m)=\frac {n^{\underline m}}{m!}=\frac {n!}{m!(n-m)!} (mn)=m!nm=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的错排:
- 前n-1个数构成一个错排,只需要把任意一个数放在 a n a_n an的位置,把n放在那个空出来的位置上。放置n有 n − 1 n-1 n−1种方案。
- 前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!
这个公式在二项式反演中给出证明,事实上,也可以通过把递推式带入的方法得到通项公式。
事实上,错排公式还可以通过多项式模拟得到,这里不讨论。
组合公式与变换技巧
排列数,圆排列数,错位排列数不常变换。
组合数公式
根据定义,显然有: ( 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个。
范德蒙德卷积公式用于特定组合数的时间复杂度优化:例题
范德蒙德卷积公式还有两种常见用法:
- 优化形如 ∑ 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)
- 对于形如 ( k x + y ) \left(^{x+y}_k\right) (kx+y)的式子,可以回套范德蒙德卷积公式,做组合变换。
顶项为变量:
拍起来之后要上下两项要加1:
∑ i = 0 n ( x n − i ) ( y i ) = ( x + y + 1 n + 1 ) \overset{n}{\underset{i=0}\sum}\left(^{n-i}_{x}\right)\left(^{i}_{y}\right)=\left(^{n+1}_{x+y+1}\right) i=0∑n(xn−i)(yi)=(x+y+1n+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−1j=1∑miwj
证明一下:
我们假设有这样的状态与转移:
也就是说,x1->x2对应的权值为{3,7,8},x2->x3对应的权值为{2,1}。
从每一集合内任选一种,做乘积。再把所有可能性加和,显然符合乘法的形式:
ans=(3+7+8)×(2+1)
推理过程显然具有普遍性。
QED.
做法可以拓展到具有相应性质的任意两种运算上(现在是 + , × +,\times +,×)。
重复元素组合问题
多重组合数
*这里说的多重组合数,不是“多重集组合数”。
将n个不同元素划分为
m
m
m个有标号集合,使得第i个集合的元素数量为
m
i
m_i
mi个,有多少种划分的可能数记作:
(
m
1
,
m
2
,
.
.
.
,
m
m
n
)
\left(^{\;\;\;\;\;\;\;\;n}_{m_1,m_2,...,m_m}\right)
(m1,m2,...,mmn)
∑
m
i
=
1
m
i
=
n
\underset{i=1}{\overset m\sum}m_i=n
i=1∑mmi=n
容易发现
(
m
n
)
=
(
n
,
n
−
m
n
)
\left(^n_m\right)=\left(^{\;\;\;\;n}_{n,n-m}\right)
(mn)=(n,n−mn)。
那么重数为 ∏ 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,...,mmn)=i∏mi!n!
多重组合数与多项式定理有关。
多重组合数公式
多重集排列数
对于一个大小为 n n n的可重集 S S S,选出其中 m m m个元素能够形成的所有不同排列的数量称为多重集排列数。
多重集排列/组合数可以使用生成函数(GF)求解。
对于可重集
S
S
S,选出其中
n
n
n个元素(即所有元素都选),能够形成的不同排列的数量有公式:
(
m
1
,
m
2
,
.
.
.
,
m
m
n
)
\left(^{\;\;\;\;\;\;\;\;n}_{m_1,m_2,...,m_m}\right)
(m1,m2,...,mmn)
其中 m m m表示可重集拥有的元素种类数, m i m_i mi表示第 i i i种元素的重数。
因此多重集的排列数等于多重组合数。
其组合意义为:假设 S S S中值为 i i i的元素数量有 m i m_i mi个,然后我们对 S S S求一个排列 P P P,同时还有一个大小为 n n n不可重集合 A A A,把 A A A的第 i i i个元素放到第 P i P_i Pi个有标号集合内,最终就得到了多重组合数的意义。
多重集组合数
对于一个大小为 n n n的可重集合 S S S,选出其中 m m m个元素能够形成的所有不同组合的数量称为多重集组合数。
多重集组合数除了可以使用生成函数求解之外,还可以使用容斥原理求解。
后记
于是皆大欢喜。