「学习笔记」组合数学

本文部分内容来自 OI-Wiki


加法 & 乘法原理#

加法原理#

完成一个工程可以有 n 类办法,ai(1in) 代表第 i 类方法的数目。那么完成这件事共有 S=a1+a2++an 种不同的方法。

乘法原理#

完成一个工程需要分 n 个步骤,ai(1in) 代表第 i 个步骤的不同方法数目。那么完成这件事共有 S=a1×a2××an 种不同的方法。

排列与组合#

排列#

n 个不同元素中,任取 mmnmn 均为自然数,下同)个元素按照一定的顺序排成一列,叫做从 n 个不同元素中取出 m 个元素的一个排列;从 n 个不同元素中取出 m(mn) 个元素的所有排列的个数,叫做从 n 个不同元素中取出 m 个元素的排列数,用符号 Anm(或者是 Pnm)表示。

Anm=n(n1)(n2)(nm+1)=n!(nm)!

公式可以这样理解:n 个人选 m 个来排队 (mn)。第一个位置可以选 n 个,第二位置可以选 n1 个,以此类推,第 m 个(最后一个)可以选 nm+1 个,得:

Anm=n(n1)(n2)(nm+1)=n!(nm)!

全排列:n 个人全部来排队,队长为 n。第一个位置可以选 n 个,第二位置可以选 n1 个,以此类推得:

Ann=n(n1)(n2)3×2×1=n!

全排列是排列数的一个特殊情况。

组合#

n 个不同元素中,任取 mn 个元素组成一个集合(不是排列),叫做从 n 个不同元素中取出 m 个元素的一个组合;从 n 个不同元素中取出 mn 个元素的所有组合的个数,叫做从 n 个不同元素中取出 m 个元素的组合数,用符号 (nm) 来表示,读作「nm」。

组合数计算公式

(nm)=Anmm!=n!m!(nm)!

如何理解上述公式?我们考虑 n 个人选 m 个出来(mn),不排队,不在乎顺序。如果在乎顺序那么就是
Anm,如果不在乎那么就要除掉重复,那么重复了多少?同样选出来的 m 个人,他们还要「全排」得 m!

组合数也常用 Cnm 表示,即 Cnm=(nm)。现在数学界普遍采用 (nm) 的记号而非 Cnm

特别地,规定当 m>n 时,Anm=(nm)=0

关于组合数的一些公式#

(n0)=(nn)=1

这个应该很好理解,不选和全选的方式就只有一种情况。


(nm)=(nnm)

这个公式可以这么理解,你在 n 个人中选走了 m 个人,另一个人把剩下的 nm 个人给选走了,对你来说,你选人的方案数为 (nm),而另一个人选人的方案数与我们是一样的,换位思考一下,倘若主动权在另一个人手中,则他选人的方案数就是 (nnm),方案数不变,两者是等价的,故得 (nm)=(nnm)


(nm)=(n1m1)+(n1m)

这个公式可以这么理解,对于从 n 个人中选 m 个人的方案数,可以分第一个人选或不选两种方案,如果第一个人选,则方案数为 (n1m1),如果第一个人不选,则方案数为 (n1m),加起来即为 (nm)

由此,我们可以得到组合数的递推公式,下面是递推求组合数的代码。

for (int i = 0; i <= n; ++ i) {
    C[i][0] = 1;
    for (int j = 1; j <= i; ++ j) {
        C[i][j] = C[i - 1][j - 1] + C[i - 1][j];
    }
}

(k1)+(k2)+(k3)++(kk)=2k1

对于 k 个数,每个数都有选或不选两种情况,总共有 2k 种情况,上面的公式包括了除了每个数都不选这 1 种情况外的所有情况,因此情况数为 2k1

同时可得到另一个公式:

(k0)+(k1)+(k2)+(k3)++(kk)=2k

还有一些别的:

i=0m(ni)(mmi)=(m+nm)(nm)i=0n(ni)2=(2nn)

插板法#

现在有 n 个完全相同的元素,要求将其分成 k 组,保证每组不为空,一共有多少种分法?

考虑在这 n 个元素形成的 n1 个空中插入 k1 个板将他们隔开,分成 k 组。

答案:(n1k1)

本质是求 x1+x2+x3++xk=n 的正整数解的组数

现在允许可以有为空的组,其余条件与上题一样

考虑借来 k 个元素,这 k 个元素分别放入 k 组,最后分好 k 组后再将这 k 个元素删掉,这样就转化成了上面的问题,将这 n+k 个元素分成 k 组,每组不能为空,公式:

(n+k1k1)=(n+k1n)

现在每组中都有限制,第 i 组内的元素个数要求不少于 ai 个,保证 i=1kain

考虑先将这 i=1kai 个元素,按照要求分在各个组里,现在还剩下 ni=1kai 个元素,转化成上面的问题,将这 ni=1kai 个元素分到 k 组里,可以有为空的组,公式:

(ni=1kai+k1k1)=(ni=1kai+k1ni=1kai)

1nn 个自然数中,选出 k 个不相邻的数的方案数。

考虑选出 nk 个位置,这样就产生了 nk+1 个空,将 k 个元素插入到这些空中,最后从前往后依次标号即可,方案数:

(nk+1k)

多重集#

有重复元素的广义集合。设 S={n1a1,n2a2,n3a3,,nkak} 表示由 n1a1n2a2n3a3 …… nkak 组成的多重集。

多重集的排列#

n=n1+n2+n3++nk,所有元素总的排列为 n!,除去相同元素的排列 i=1kni=n1!n2!n3!nk!,最后的全排列公式为:

n!i=1kni=n!n1!n2!n3!nk!

具体地,你可以认为你有 k 种不一样的球,每种球的个数分别是 n1,n2,,nk,且 n=n1+n2++nk。这 n 个球的全排列数就是 多重集的排列数。多重集的排列数常被称作 多重组合数

多重组合数符号 (nn1,n2,n3,,nk)=n!n1!n2!n3!nk!=n!i=1kni

多重集的组合#

S={n1a1,n2a2,,nkak} 表示由 n1a1n2a2,…,nkak 组成的多重集。那么对于整数 r(r<ni,i[1,k]),从 S 中选择 r 个元素组成一个多重集的方案数就是 多重集的组合数。这个问题等价于 x1+x2++xk=r 的非负整数解的数目,可以用插板法解决,参考上面插板法的问题二,公式:

(r+k1k1)

上面对于 r 的限制是 r(r<ni,i[1,k]),现在对于 r 的限制是 ri=1knk,这里要用容斥,最后的结果是:

Ans=p=0k(1)pA(k+r1AnAipk1)

其中 A 是充当枚举子集的作用,满足 |A|=p, Ai<Ai+1

圆排列#

n 个人全部来围成一圈,所有的排列数记为 Qnn。考虑其中已经排好的一圈,从不同位置断开,又变成不同的队列。 所以有

Qnn×n=AnnQn=Annn=(n1)!

由此可知部分圆排列的公式:

Qnr=Anrr=n!r×(nr)!

二项式定理#

之前写了:「学习笔记」从二项式定理到多项式定理

抽屉原理(鸽巢原理)#

现在有 n+1 个东西,放到 n 个抽屉里面去,那么肯定有一个抽屉放了 2 个东西。

不信你自己试试看。

让我们扩展一下:现在要把 kn+1 个东西放到 n 个抽屉中去,则至少有 1 个抽屉至少有 k+1 个东西。

定理很简单,这类题目真正难的地方在于你要能看出它是抽屉原理,要知道谁是抽屉,谁是东西。

容斥原理#

之前写了:「学习笔记」容斥原理

错位排列#

错位排列(derangement)是没有任何元素出现在其有序位置的排列。即,对于 1n 的排列 P,如果满足 Pii,则称 Pn 的错位排列。

把错位排列问题具体化,考虑这样一个问题:

n 封不同的信,编号分别是 1,2,3,4,5,现在要把这五封信放在编号 1,2,3,4,5 的信封中,要求信封的编号与信的编号不一样。问有多少种不同的放置方法?
假设考虑到第 n 个信封,初始时暂时把第 n 封信放在第 n 个信封中,然后考虑两种情况的递推:

  • 前面 n1 个信封全部装错;

  • 前面 n1 个信封有一个没有装错其余全部装错。

对于第一种情况,前面 n1 个信封全部装错:因为前面 n1 个已经全部装错了,所以第 n 封只需要与前面任意一个位置交换即可,总共有 Dn1×(n1) 种情况。
对于第二种情况,前面 n1 个信封有一个没有装错其余全部装错:考虑这种情况的目的在于,若 n1 个信封中如果有一个没装错,那么把那个没装错的与 n 交换,即可得到一个全错位排列情况。
其他情况,不可能通过一次操作来把它变成一个长度为 n 的错排。
于是可得,错位排列数满足递推关系:

Dn=(n1)(Dn1+Dn2)

斯特林数#

第二类斯特林数#

第二类斯特林数(斯特林子集数) {nk},也可记做 S(n,k),表示将 n 个两两不同的元素,划分为 k 个互不区分的非空子集的方案数。
递推式:

{nk}={n1k1}+k{n1k}

边界是 {n0}=[n=0]

考虑用组合意义来证明。

我们插入一个新元素时,有两种方案:
将新元素单独放入一个子集,有 {n1k1} 种方案;

将新元素放入一个现有的非空子集,有 k{n1k} 种方案。

根据加法原理,将两式相加即可得到递推式。

第一类斯特林数#

第一类斯特林数(斯特林轮换数)[nk],也可记做 s(n,k),表示将 n 个两两不同的元素,划分为 k 个互不区分的非空轮换的方案数。

一个轮换就是一个首尾相接的环形排列。我们可以写出一个轮换 [A,B,C,D],并且我们认为 [A,B,C,D]=[B,C,D,A]=[C,D,A,B]=[D,A,B,C],即,两个可以通过旋转而互相得到的轮换是等价的。注意,我们不认为两个可以通过翻转而相互得到的轮换等价,即 [A,B,C,D][D,C,B,A]

递推式:

[nk]=[n1k1]+(n1)[n1k]

边界是 [n0]=[n=0]

该递推式的证明可以考虑其组合意义。
我们插入一个新元素时,有两种方案:

  • 将该新元素置于一个单独的轮换中,共有 [n1k1] 种方案;

  • 将该元素插入到任何一个现有的轮换中,共有 (n1)[n1k] 种方案。

根据加法原理,将两式相加即可得到递推式。

组合数的题目#

n 个数,1,2,3,4,5,6,,选 m 个数,不计顺序,一个数可以选多次,求方案数。

假设选出的数是 a1,a2,a3,,am,这 m 个数不能重复,且递增选出。方案数:(nm)
这是我们所知道的,aa1<a2<a3<<amn

但是,对于这个题来说,情况是 1b1b2b3bmn,因此我们需要转化过去,即

aa1<a2<a3<<amn1b1b2b3bmn

考虑构造,C1=b1,C2=b2+1,C3=b3+2,,Cm=bm+m1

那么,1b1b2b3bmn 就转化为了 1C1<C2<C3<Cmn+m1

我们的方案数也呼之欲出了:(n+m1m)

作者:yifan0305

出处:https://www.cnblogs.com/yifan0305/p/17485986.html

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

转载时还请标明出处哟!

posted @   yi_fan0305  阅读(100)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
历史上的今天:
2022-08-30 「刷题记录」LOJ/一本通提高篇 深搜的剪枝技巧
more_horiz
keyboard_arrow_up light_mode palette
选择主题
menu
点击右上角即可分享
微信分享提示