组合数学系列
前言
该系列主要结合作者所学编写而成,如有错误,请大家多多指正。
组合数学为计算机学科的一门必修课,其中的大量模型、公式均可在计算机相关学科中得到应用。因此,具备一定的组合数学知识对学习计算机有着很大帮助。
本文中会有着许多例题来供大家参考。
第一章 排列组合
1.1、加法法则与乘法法则
【加法法则】设具有特征 A A A的事件有 m m m个,具有 B B B特征的事件有 n n n个,则具有特征 A A A或特征 B B B的事件有 m + n m+n m+n个。
集合论语言:
若
∣
A
∣
=
m
|A|=m
∣A∣=m,
∣
B
∣
=
n
|B|=n
∣B∣=n,
A
∩
B
=
∅
A\cap B=\varnothing
A∩B=∅,则
∣
A
∪
B
∣
=
m
+
n
|A\cup B|=m+n
∣A∪B∣=m+n。
【例】某班选修企业管理的有
18
18
18人,不选
的有
10
10
10人,则该班共有
18
+
10
=
28
18+10=28
18+10=28人。
【例】北京每天直达上海的客车有 5 5 5次,客机有 3 3 3次, 则每天由北京直达上海的旅行方式有 5 + 3 = 8 5+3=8 5+3=8种。
【乘法法则】设具有特征 A A A的事件有 m m m个,具有 B B B特征的事件有 n n n个,则特征 A A A与特征 B B B有 m ⋅ n m\cdot n m⋅n种匹配方式。
集合论语言:
若
∣
A
∣
=
m
|A|=m
∣A∣=m,
∣
B
∣
=
n
|B|=n
∣B∣=n,
A
×
B
=
{
(
a
,
b
)
∣
a
∈
A
,
b
∈
B
}
A\times B=\lbrace\lparen a,b\rparen|a\in A,b\in B\rbrace
A×B={(a,b)∣a∈A,b∈B},则
∣
A
×
B
∣
=
m
⋅
n
|A\times B|=m\cdot n
∣A×B∣=m⋅n。
【例】某种字符串由两个字符组成,第一个字符可选自 { a , b , c , d , e } \lbrace a,b,c,d,e\rbrace {a,b,c,d,e},第二个字符可选自 { 1 , 2 , 3 } \lbrace 1,2,3\rbrace {1,2,3},则这种字符串共有 5 × 3 = 15 5\times 3=15 5×3=15个。
【例】从A到B有三条道路,从B到C有两条道路,则从A经B到C有 3 × 2 = 6 3\times 2=6 3×2=6条道路。
在乘法法则中要注意事件 A A A和事件 B B B的相互独立性。
【例】求小于10000的含1的正整数的个数。
小于10000的不含1的正整数可看作4位数,但0000除外。
故有
9
×
9
×
9
×
9
−
1
=
6560
9\times 9\times 9\times 9-1=6560
9×9×9×9−1=6560个
因此,含1的有:
9999
−
6560
=
3439
9999-6560=3439
9999−6560=3439个
【例】求小于10000的含0的正整数的个数。
“含0”不可直接套用“含1”的解法,比如:0019含1但不含0.
在组合的习题中有许多类似的隐含的规定。
不含0的1位数有
9
9
9个,2位数有
9
2
9^2
92个,3位数有
9
3
9^3
93个,4位数有
9
4
9^4
94个
不含
0
0
0小于
10000
10000
10000的正整数有
9
+
9
2
+
9
3
+
9
4
=
(
9
5
−
1
)
/
(
9
−
1
)
=
7380
9+9^2+9^3+9^4=(9^5-1)/(9-1)=7380
9+92+93+94=(95−1)/(9−1)=7380个
含
0
0
0小于
10000
10000
10000的正整数有
9999
−
7380
=
2619
9999-7380=2619
9999−7380=2619个
1.2、排列与组合
【排列定义】 从n个不同的元素中,取r个不重复的元素,按次序排列,称为从n个中取r个的无重排列。排列的全体组成的集合数用 P ( n , r ) \Rho(n,r) P(n,r)表示。排列的个数用 P ( n , r ) P(n,r) P(n,r)表示。当r=n时称为全排列。一般不说可重即无重。可重排列的相应记号为 P ‾ ( n , r ) \overline{\Rho}(n,r) P(n,r), P ‾ ( n , r ) \overline{P}(n,r) P(n,r)。
【例】从n个不同的球中,取出r个,放入r个不同的盒子里,每盒1个。第1个盒子有n种选择,第2个有n-1种选择,······,第r个有n-r+1种选择。求
P
(
n
,
r
)
P(n,r)
P(n,r)。
P
(
n
,
r
)
=
n
(
n
−
1
)
⋅
⋅
⋅
⋅
⋅
⋅
(
n
−
r
+
1
)
P(n,r)=n(n-1)······(n-r+1)
P(n,r)=n(n−1)⋅⋅⋅⋅⋅⋅(n−r+1),有时也用
[
n
]
r
[n]_r
[n]r记
n
(
n
−
1
)
⋅
⋅
⋅
⋅
⋅
⋅
(
n
−
r
+
1
)
n(n-1)······(n-r+1)
n(n−1)⋅⋅⋅⋅⋅⋅(n−r+1).
【组合定义】从n个不同元素中取r个不重复的元素组成一个子集,而不考虑其元素的顺序,称为从n个中取r个的无重组合。
组合的全体组成的集合用 C ( n , r ) \cnums(n,r) C(n,r)表示,组合的个数用 C ( n , r ) C(n,r) C(n,r)表示,对应于可重组合有记号 C ‾ ( n , r ) \overline{\cnums}(n,r) C(n,r), C ‾ ( n , r ) \overline{C}(n,r) C(n,r)。
【例】由上例,若球不同,盒子相同,则是从n个中取r个的组合的模型。
C
(
n
,
r
)
=
(
n
r
)
=
n
!
r
!
(
n
−
r
)
!
C(n,r)=\begin{pmatrix}n\\r\end{pmatrix}={\frac {n!} {r!(n-r)!}}
C(n,r)=(nr)=r!(n−r)!n!
故有, C ( n , r ) ⋅ r ! = P ( n , r ) C(n,r)\cdot{r!}=P(n,r) C(n,r)⋅r!=P(n,r)
【例】有5本不同的日文书,7本不同的英文书,10本不同的中文书。
1)取2本不同文字的书;
5
×
7
+
5
×
10
+
7
×
10
=
155
5×7+5×10+7×10=155
5×7+5×10+7×10=155
2)取2本相同文字的书;
C
(
5
,
2
)
+
C
(
7
,
2
)
+
C
(
10
,
2
)
=
10
+
21
+
45
=
76
C(5,2)+C(7,2)+C(10,2)=10+21+45=76
C(5,2)+C(7,2)+C(10,2)=10+21+45=76
3)任取两本书
C
(
5
+
7
+
10
,
2
)
=
(
5
+
7
+
10
2
)
=
231
C(5+7+10,2)=\begin{pmatrix}{5+7+10}\\{2}\end{pmatrix}=231
C(5+7+10,2)=(5+7+102)=231
【例】从[1,300]中取3个不同的数,使这3个数的和能被3整除,有多少种方案?
将
[
1
,
300
]
[1,300]
[1,300]分成3类:
A
=
{
i
∣
i
=
1
(
m
o
d
3
)
}
=
{
1
,
4
,
7
,
…
,
298
}
A=\lbrace{i}|{i=1(\bmod3)}\rbrace=\lbrace{1,4,7,\dots,298}\rbrace
A={i∣i=1(mod3)}={1,4,7,…,298},
B
=
{
i
∣
i
=
2
(
m
o
d
3
)
}
=
{
2
,
5
,
8
,
…
,
299
}
B=\lbrace{i}|{i=2(\bmod3)}\rbrace=\lbrace{2,5,8,\dots,299}\rbrace
B={i∣i=2(mod3)}={2,5,8,…,299},
C
=
{
i
∣
i
=
3
(
m
o
d
3
)
}
=
{
3
,
6
,
9
,
…
,
300
}
C=\lbrace{i}|{i=3(\bmod3)}\rbrace=\lbrace{3,6,9,\dots,300}\rbrace
C={i∣i=3(mod3)}={3,6,9,…,300},
要满足条件,有四种解法:
1)3个数同属于A;
2)3个数同属于B;
3)3个数同属于C;
4)A,B,C各取一数。
故共有
3
C
(
100
,
3
)
+
10
0
3
=
485100
+
1000000
=
1485100
3C(100,3)+100^3=485100+1000000=1485100
3C(100,3)+1003=485100+1000000=1485100
【例】某车站有6个入口处,每个入口处每次只能进一人,一组9个人进站的方案有多少?
进站方案可表示成:00000000011111
“1”表示门框,“0”表示人,其中“0”是不同元,“1”是相同元。所以,每一种进站方案都可以被表示为上面14个元素的一种排列。
【解法1】
标号可产生
5
!
5!
5!个14个元的全排列(门框就相当于之前上述例子的“相同的盒子”,也就是r),故设x为所求方案,则
x
⋅
5
!
=
14
!
x\cdot5!=14!
x⋅5!=14!
∴
x
=
14
!
5
!
=
726485760
\therefore x={\frac {14!} {5!}}=726485760
∴x=5!14!=726485760
【解法2】
在14个元的排列中先确定“1”的位置,有
C
(
14
,
5
)
C(14,5)
C(14,5)种选择,再确定人的位置,有
9
!
9!
9!种选择。
∴
C
(
14
,
5
)
⋅
9
!
\therefore C(14,5)\cdot 9!
∴C(14,5)⋅9!即所求
【解法3】
把全部选择分解成若干步,使每步宜于计算。不妨设9个人编成1至9号。1号有6种选择;2号除可有1号的所有选择外(就算当前选择的门有人,大不了排队嘛!),还可(也必须)选择当与1号同一门时在1号的前面还是后面,故2号有7种选择(一开始的6种里已经有一个前面或后面,所以再来一种不一样的,就成了7种);3号的选择方法同2号(针对2号的前面和后面,毕竟一号的已经被算进去了),故共有8种。
以此类推,9号有14种选择。
故所求方案为
[
14
]
9
[14]_9
[14]9。
1.3、模型转换
- “一一对应”概念是一个在计数中极为基本的概念。一一对应既是单射又是满射。
- 如我们说A集合有n个元素 |A|=n,无非是建立了将A中元与[1,n]元一一对应的关系。
- 在组合计数时往往借助于一一对应实现模型转换。
- 比如要对A集合计数,但直接计数有困难,于是可设法构造一易于计数的B,使得A与B一一对应。
【例】简单格路问题 |(0,0)→(m,n)|=( )
从 (0,0)点出发沿x轴或y轴的正方向每步
走一个单位,最终走到(m,n)点,有多少
条路径?
无论怎样走法,在x方向上总共走m步,在y方向上总共走n步。若用一个x表示x方向上的一步,一个字母y表示y方向上的一步。
则(0,0)→(m,n)的每一条路径可表示为m个x与n个y的一个有重排列。将每一个有重排列的x与y分别编号,可得m!n!个m+n元的无重全排列。
设所求方案数为
P
(
m
+
n
;
m
,
n
)
P(m+n;m,n)
P(m+n;m,n)
则
P
(
m
+
n
;
m
,
n
)
⋅
m
!
⋅
n
!
=
(
m
+
n
)
!
P(m+n;m,n)\cdot{m!}\cdot{n!}=(m+n)!
P(m+n;m,n)⋅m!⋅n!=(m+n)!
故
P
(
m
+
n
;
m
,
n
)
=
(
m
+
n
)
!
m
!
n
!
=
(
m
+
n
m
)
=
(
m
+
n
n
)
=
C
(
m
+
n
,
m
)
P(m+n;m,n)={\frac {(m+n)!} {m!n!}}=\begin{pmatrix}{m+n}\\{m}\end{pmatrix}=\begin{pmatrix}{m+n}\\{n}\end{pmatrix}=C(m+n,m)
P(m+n;m,n)=m!n!(m+n)!=(m+nm)=(m+nn)=C(m+n,m)
设c≥a,d≥b,则由(a,b)到(c,d)的简单格路数为
∣
(
a
,
b
)
(
c
,
d
)
∣
=
(
(
c
−
a
)
+
(
d
−
b
)
c
−
a
)
\begin{vmatrix}(a,b)(c,d)\end{vmatrix}=\begin{pmatrix}{(c-a)+(d-b)}\\{c-a}\end{pmatrix}
∣
∣(a,b)(c,d)∣
∣=((c−a)+(d−b)c−a)。
【例 整花活】在上例的基础上若设m<n,求(0,1)点到(m,n)点不接触对角线x=y的格路的数目 (“接触”包括“穿过”)
从(0,1)点到(m,n)点的格路,有的接触x=y,有的不接触。
对每一条接触x=y的格路,做(0,1)点到第一个接触点部分关于x=y的对称格路,这样得到一条从(1,0)到(m,n)的格路。
容易看出从(0,1)到(m,n)接触x=y的格路与 (1,0)到(m,n)的格路(必穿过x=y)一一对应
故所求格路数为
(
m
+
n
−
1
m
)
−
(
m
+
n
−
1
m
−
1
)
=
\begin{pmatrix}{m+n-1}\\{m}\end{pmatrix}-\begin{pmatrix}{m+n-1}\\{m-1}\end{pmatrix}=
(m+n−1m)−(m+n−1m−1)=
【例 再次魔改】若条件改为可接触但不可穿过,则限制线要向下或向右移一格,得x-y=1,(0,0)关于x-y=1的对称点为(1,-1)。
所求格路数为
(
m
+
n
m
)
−
(
m
+
n
m
−
1
)
=
(
m
+
n
)
!
m
!
n
!
−
(
m
+
n
)
!
(
m
−
1
)
!
(
n
+
1
)
!
=
n
+
1
−
m
n
+
1
(
m
+
n
m
)
\begin{pmatrix}{m+n}\\{m}\end{pmatrix}-\begin{pmatrix}{m+n}\\{m-1}\end{pmatrix}={\frac {(m+n)!} {m!n!}}-{\frac {(m+n)!} {(m-1)!(n+1)!}}={\frac {n+1-m} {n+1}}{\begin{pmatrix}{m+n}\\{m}\end{pmatrix}}
(m+nm)−(m+nm−1)=m!n!(m+n)!−(m−1)!(n+1)!(m+n)!=n+1n+1−m(m+nm)
格路也是一种常用模型
【例】在100名选手之间进行淘汰赛(即一场的比赛结果,失败者退出比赛),最后产生一名冠军,问要举行几场比赛?
一种常见的思路是按轮计场。
另一种思路是淘汰的选手与比赛(按场计)一一对应。99场比赛。
【例】
C
n
H
2
n
+
2
C_nH_{2n+2}
CnH2n+2是碳氢化合物,随着n的不同有下列不同的枝链:
这说明对应
C
n
H
2
n
+
2
C_nH_{2n+2}
CnH2n+2的枝链是有3n+2个顶点的一棵树,其中n个顶点与之关联的边数为4;其它2n+2个顶点是叶子。对于这样结构的每一棵树,就对应有一种特定的化合物。从而可以通过研究具有上述性质的树找到不同的碳氢化合物
C
n
H
2
n
+
2
C_nH_{2n+2}
CnH2n+2。(这个例题就是补充下知识,为下面例题准备)
【例】(Cayley定理) n个有标号的顶点的树的数目等于
n
n
−
2
n^{n-2}
nn−2。
生长点不是叶子,每个生长点是[1,n]中的任一元.有n种选择。两个顶点的树是唯一的。
【例】给定一棵有标号的树,求序列。
边上的标号表示摘去叶的顺序。(摘去一个叶子相应去掉一条边)。
逐个摘去标号最小的叶子,叶子的相邻顶点(不是叶子,是内点)形成一个序列,序列的长度为n-2。
以此类推,得到序列31551,长度为7-2 = 5这是由树形成序列的过程。
【例】由序列31551形成树。
由序列31551得到一个新序列111233455567,生成的过程是首先将31551排序得到11355,因为序列31551的长度为5,得到按升序排序的序列1234567,序列的长度为5+2(即n+2),然后将11355按照大小插入到序列1234567中,得到111233455567。然后将两个序列排在一起得
(
31551
111233455567
)
\begin{pmatrix}{31551}\\{111233455567}\end{pmatrix}
(31551111233455567)。
进行变换:
依此类推,减到下面剩最后两个元素,这两个元素形成最后一条边。最后形成树。
上述算法描述:
给定序列 b = ( b 1 b 2 … b n − 2 ) b=(b_1b_2…b_{n-2}) b=(b1b2…bn−2)设 a = ( 123 … ( n − 1 ) n ) a=(123…(n-1) n) a=(123…(n−1)n)将 b b b的各位插入 a a a,得 a ′ a' a′,对 ( b a ′ ) \begin{pmatrix}{b}\\{a'}\end{pmatrix} (ba′)做操作。 a ’ a’ a’是 2 n − 2 2n-2 2n−2个元的可重非减序列。
操作是从 a ′ a' a′中去掉最小无重元,设为 a 1 a_1 a1,再从 b b b和 a ′ a' a′中各去掉一个 b b b中的第一个元素,设为 b 1 b_1 b1,则无序对 ( a 1 , b 1 ) (a_1,b_1) (a1,b1)是一条边。重复这一操作,得 n − 2 n-2 n−2条边,最后 a ′ a' a′中还剩一条边,共 n − 1 n-1 n−1条边,正好构成一个树。 b b b中每去掉一个元, a ′ a' a′中去掉2个元。
由算法知由树 T T T得 b = ( b 1 b 2 … b n − 2 ) b=(b_1b_2…b_{n-2}) b=(b1b2…bn−2),反之,由 b b b可得 T T T。即 f : T → b f:T→b f:T→b是一一对应。
由序列确定的长边过程是不会形成回路的。因任意长出的边 (u , v) 若属于某回路,此回路中必有一条最早生成的边,不妨就设为 (u , v) ,必须使u,v都在长出的边中重复出现,但照算法u,v之一从下行消失,不妨设为u,从而不可能再生成与u有关的边了,故由 ( b a ′ ) \begin{pmatrix}{b}\\{a'}\end{pmatrix} (ba′)得到的边必构成一个n个顶点的树。
证明:
1.4、全排列的生成算法
【全排列的生成算法】就是对于给定的字符集,用有效的方法将所有可能的全排列无重复无遗漏地枚举出来。
字典序法
对给定的字符集中的字符规定了一个先后关系,在此基础上规定两个全排列的先后是从左到右逐个比较对应的字符的先后。
【例】字符集{1,2,3},较小的数字较先,这样按字典序生成的全排列是:
123,132,213,231,312,321。
一个全排列可看做一个字符串,字
符串可有前缀、后缀。
1)生成给定全排列的下一个排列,所谓一个的下一个就是这一个与下一个之间没有其他的。这就要求这一个与下一个有尽可能长的共同前缀,也即变化限制在尽可能短的后缀上。
【例】求839647521的下一个排列。
839647521是1–9的排列。1—9的排列最前面的是123456789,最后面的是987654321,从右向左扫描若都是增的,就到了987654321,也就没有下一个了。否则找出第一次出现下降的位置。
k下标的数要比j下标的数大,并且距离尽可能地远,j好理解不解释。把这俩下标的数交换位置,然后把现在k下标以后的数翻转,就是目标排列了。
2)计算给定排列的序号
839647521的序号即先于此排列的排列的个数。
将先于此排列的排列按前缀分类。
将8!,7!,…,1!前面的系数抽出,放在一起得到72642321,由于72642321是计算排列839647521的序号的中间环节,因此称为中介数。中介数记录的是当前数字的右边比当前数字小的数字的个数。
这种题一般都是先确定”1“的位置。解释下上图,首先发现中介数最后一位是1,也就是说第八位数字右边有一个比它小的,这不就是1嘛。再看中介数中的”7“,右边有8个数,比7个数大,那就是”8“呗,要是”9“的话,”7“不就变成”8“了?跟解数组一样,都是根据周边条件来判断当前位置的数字。
还有一种方法,定”9“的位置
由72642321推算出839647521,中介数右端加一个0扩成9位,先定1,每定一位,其左边未定位下加一点,从(位-位下点数=0)的位中选最左的。
这章完了!