Jerry's Blog

Back

加法原理#

如果解决某个问题的方案可以分为互不重叠的几类,那么把每一类的方案数加起来,就能得到总的方案数.

乘法原理#

如果把解决某个问题的方案可以分成几个步骤,那么把每一步的方案数依次乘起来,就能得到总的方案数.

排列数和组合数#

排列数

假定一共有 nn 个人,我们要从中选择 mm 个人,让他们排成一排,拍一张照,最多可能有多少种不同的照片呢?

像这样的题目,从 nn 个不同的元素中任取 m(mn)m(m\leq n) 个元素的所有排列的个数,叫做从 nn 个不同的元素中取出 mm 个元素的排列数,记作 AnmA^m_n

那么,AnmA^m_n 到底是多少呢?首先,考虑第一个位置,由于有 nn 个人,所以有 nn 种情况,第二个位置呢?由于已经被选掉了一个人,所以第二个位置就有 n1n-1 种选择,以此类推,第 mm 个位置就有 nm+1n-m+1 种可能,它们是解决问题的几个步骤,所以使用乘法连接.

一般的:

Anm=n(n1)(n2)(nm+1)=n!(nm)!\begin{aligned} A^m_n &=n(n-1)(n-2)\cdots(n-m+1)\\ &=\frac{n!}{(n-m)!} \end{aligned}

特殊的:

Ann=n!A^n_n=n!

其中,形如 n!n! 的运算是阶乘,定义 n!=n(n1)(n2)×1n! = n(n-1)(n-2)\cdots\times1

组合数

假定你到一个洞穴去冒险,洞穴中有 nn 种互不相同的宝物,但是你的袋子只能装下 mm 件,你有多少种拿取的方式呢?

考虑一个有 nn 个元素的集合 TT,其拥有 mm 个元素的子集 SS 满足 STS\subseteq T,符合条件的 SS 的个数即为组合数,记作 CnmC^m_n

同样的,为了求取 CnmC^m_n 的值,我们可以优先求取 AnmA^m_n 的值,然后,由于选出的 mm 个元素应当不计顺序,故需排除上述选法中的重复:对于上述的每一个集合 SS,在排列数中都被正好地重复计算了 AmmA^m_m 次.

所以,一般的:

Cnm=AnmAmm=n!m!(nm)!\begin{aligned} C^m_n &=\frac{A^m_n}{A^m_m}\\ &=\frac{n!}{m!(n-m)!} \end{aligned}

特殊的,Cmm=1C^m_m=1

以下是一个使用费马小定理(参见 取模与逆元)和组合数公式来求组合数的例子:

小球八题#

已知有 nn 个球,将其放入 mm 个盒子里,有几种放法呢?根据球或盒子是否相同和是否允许空盒,关于这类题有 8 个变种,我们可以列出以下表格:

类型每个球是否完全等价每个盒子是否完全等价是否允许空盒
A
B
C
D
E
F
G
H

类型 G#

这个类型最简单,不同的小球,不同的盒子,类似下面这个问题:

nn 个人,mm 个景点,每个人只能去 1 个景点,求不同方案数.

由于每个人有 mm 种选择方式且人与人之间互不干扰,所以总共方案数为 mnm^n

类型 D#

考虑这样一个场景,有 mm 个人在分蛋糕,这个蛋糕是一个长方形的,长 nn 个单位,宽 1 个单位,且每个人都要有蛋糕,且长宽必须是整数.

我们考虑竖着切,将其切成 mm 份,就是要在 n1n-1 个空隙里选择 m1m-1 空隙,切一刀,所以,一共有 Cn1m1C^{m-1}_{n-1} 种方案.

类型 C#

相对于类型 D 来说,类型 C 允许有人没分到蛋糕,因此,我们先让每个人拿一个单位的蛋糕,所以一共就有 n+mn+m 个单位,这样就转换为类型 D 了,答案是 Cn+m1m1C^{m-1}_{n+m-1}

类型 E#

考虑这样一个情况,有 nn 个不同颜色的糖,需要分成 mm 堆.

这个问题可以用 dp 解决.

状态定义:定义 dp[t][k] 表示在前 t 个糖中分成 k 堆的方案数.

初始状态dp[1][k]=1,1kmdp[1][k]=1,1\leq k\leq m

状态转移方程

假定有一颗新的糖,你有两种选择,一种是新开一堆,另一种是将其放到之前的任意一堆之中.

这两种贡献中,其一是新开一堆这种方式的贡献,则之前的状态可以表示为 dp[t1][k1]dp[t-1][k-1],其二是放到之前的堆中这种方式的贡献,则之前的状态可以表示为 dp[t1][k]dp[t-1][k],由于有 kk 堆,所以这种方式一共有 kk 种情况.

综合一下,可得:dp[t][k]=dp[t1][k1]+dp[t1][k]×kdp[t][k]=dp[t-1][k-1]+dp[t-1][k]\times k

最终状态

由于允许空盒,所以答案就是 dp[n][1]+dp[n][2]++dp[n][m]dp[n][1]+dp[n][2]+\cdots +dp[n][m],也就是:

i=1mdp[n][i]\sum^{m}_{i=1}dp[n][i]

类型 F#

类似类型 E,但是由于不允许为空,所以最终状态是 dp[n][m]dp[n][m]

类型 H#

类似类型 F,但是,对于 F 中的每一种情况,由于盒子是不同的,都会有组合相同但顺序不同的 m!m! 种变体,所以答案是 dp[n][m]×m!dp[n][m]\times m!

类型 A#

已知有 nn 个一模一样的乒乓球,将其装进 mm 个一样的盒子里,有几种分法呢?由于每个盒子都是一样的,我们不妨规定前面盒子里球的数量必须比后面盒子里的多.

状态定义:定义 dp[t][k] 表示对于前 tt 个小球,放 kk 个盒子的方案数.

初始状态dp[1][k]=1,1kmdp[1][k]=1,1\leq k\leq m

状态转移方程

假定最后一个盒子是空盒,那么可以把那个空盒去掉:dp[t][k]dp[t][k1]dp[t][k] \Rightarrow dp[t][k-1]

假定最后一个盒子不为空,那么由于最后一个盒子的球的数量小于前面的任何一个盒子,所以,在这种情况下,没有任何一个盒子为空,所以,我们不妨将每个盒子都取出来一个:dp[t][k]dp[tk][k]dp[t][k]\Rightarrow dp[t-k][k]

综合一下:dp[t][k]=dp[t][k1]+dp[tk][k]dp[t][k] = dp[t][k-1]+dp[t-k][k]

最终状态

由于允许空盒,所以答案就是 dp[n][1]+dp[n][2]++dp[n][m]dp[n][1]+dp[n][2]+\cdots +dp[n][m],也就是:

i=1mdp[n][i]\sum^{m}_{i=1}dp[n][i]

不难发现,和类型 E 的最终状态是一样的.

类型 B#

类似类型 A,但是由于不允许为空,所以最终状态是 dp[n][m]dp[n][m]

组合数学
https://blog.jerrylab.top/blog/oi/%E6%95%B0%E6%95%B0/1-%E7%BB%84%E5%90%88%E6%95%B0%E5%AD%A6
Author Jerry
Published at 2026年3月4日