组合数学基础

排列组合

组合数

\[\binom{n}{m} = n \times (n-1) \times (n-2) \times \cdots \times (n-m+1) = \dfrac{n!}{(n-m)!m!} \]

另一个更加通用的形式为

\[\dbinom{n}{m} = \dfrac{n^{\underline{m}}}{m!} \]

其中 \(n^{\underline{m}}\) 代表下降幂,值为 \(\prod_{i = 0}^{m - 1}(n - i)\)

这个通用形式可以把组合数的上指标扩展到任意实数,但在算法竞赛中,我们通常只关心 \(n\)\(m\) 都是非负整数的情况,因此本文中出现的数默认非负。

组合数 \(\dbinom{n}{m}\) 可以视作一个关于 \(n\)\(m\) 次多项式

代码实现

注:都是在取模意义下讨论的。不讨论暴力做法。

  1. 利用杨辉/帕斯卡恒等式递推。(我们将会在组合恒等式一章中看到它)

    Code
    for(int i = 0; i <= n; i++) binom[i][0] = 1;
    for(int i = 1; i <= n; i++) {
        for(int j = 1; j <= i; j++) {
            binom[i][j] = (binom[i - 1][j - 1] + binom[i - 1][j]) % MOD;
        }
    }

    预处理时间复杂度 \(O(nm)\)。单次查询时间复杂度 \(O(1)\)

    该方法的优势在于不需要逆元,适合在模数不是质数的情况下使用。(如 [清华集训2012] 序列操作

  2. 利用 \(\dbinom{n}{m} = \dfrac{n!}{(n-m)!m!}\) 计算。

    首先可以线性预处理阶乘,于是分子搞定。

    至于分母,我们需要计算阶乘的逆元。这也是可以线性计算的。首先要求出 \(\operatorname{inv}(n!)\),然后倒序枚举 $ (n-1) \sim 1$ 的自然数,通过把 \(\operatorname{inv}((i+1)!)\) 乘上 \(i+1\) 以约掉分母中的 \(i+1\),得到 \(\operatorname{inv}(i!)\)

    Code
    void init() {
        fact[0] = 1;
    	for(int i = 1; i <= n; i++) fact[i] = fact[i-1] * i % MOD;
        fact_inv[n] = getinv(fact[n]); // getinv 可以通过快速幂/扩欧实现
        for(int i = n - 1; i >= 0; i--) fact_inv[i] = fact_inv[i+1] * (i+1) % MOD;
    }
    int binom(int n, int m) {
        return fact[n] * fact_inv[n - m] % MOD * fact_inv[m] % MOD;
    }

    时间复杂度 \(O(n) \sim O(1)\)(这里忽略了预处理中求 \(n!\) 逆元的时间复杂度)。

多重集的排列数/多重组合数

总共有 \(n\) 个物品,这些物品分为 \(k\) 种,第 \(i\) 种物品有 \(n_i\) 个,相同种类的物品是不可区分的,则这 \(n\) 个物品的排列数为

\[\binom{n}{n_1, n_2, \cdots, n_k} = \frac{n!}{\prod_{i=1}^{k} n_i!} \]

解释:如果所有物品都不同,排列数有 \(n!\) 个。但考虑到相同种类的物品不可区分,每种排列实际上被算了 \(\prod_{i=1}^{k} n_i!\)​ 次,需要除掉。

推论:考虑另一个问题:有 \(n\) 个不同的元素,要分成 \(k\) 组,第 \(i\) 组有 \(n_i\) 个元素,求有多少种分法。

可以建立一个多重集的排列到分法的一一对应。因此这两个问题的答案是相同的,分法的数量也是 \(\dbinom{n}{n_1, n_2, \cdots, n_k}\)

方程的整数解个数(插板法)

  1. 已知方程 \(x_1 + x_2 + \cdots + x_k = n\),求满足方程的整数解的个数。

    解:个数为

    \[\binom{n-1}{k-1} \]

  2. 已知方程 \(x_1 + x_2 + \cdots + x_k = n\),求满足方程的非负整数解的个数。

    解:构造方程 \(y_1 + y_2 + \cdots + y_k = n + k\),其中 \(y_i = x_i + 1\)。该方程的正整数解个数与原方程的非负整数解个数相同(可以构造出一个一一对应关系),而该方程的正整数解个数可以通过上文的方法计算。所以答案为

    \[\binom{n + k - 1}{k - 1} \]

  3. 已知方程 \(x_1 + x_2 + \cdots + x_k = n\),且 \(\forall 1\le i \le n, x_i \ge a_ i\),求满足方程的非负整数解的个数。

  4. 已知方程 \(x_1 + x_2 + \cdots + x_k = n\),且 \(\forall 1\le i \le n, x_i \le a_ i\),求满足方程的非负整数解的个数。

组合恒等式

O. 阶乘展开式

\[\boxed{\binom{n}{m} = \dfrac{n!}{(n-m)!m!}} \]

即定义式。为了完整,放在第零个位置。

I. 对称恒等式

\[\boxed{\dbinom{n}{m} = \dbinom{n}{n - m}} \]

使用组合意义证明:从 \(n\) 个物品中选择 \(m\) 个物品的方案数和从 \(n\) 个物品中\(m\) 个物品的方案数一一对应,而后者正是 \(\dbinom{n}{n - m}\)

II. 吸收恒等式

\[\boxed{\dbinom{n}{m} = \dfrac{n}{m}\dbinom{n - 1}{m - 1}} \]

把式子展开成定义式就可以立即证明这个恒等式。它告诉我们可以将一些系数移进或移出组合数。当把系数移进去时,就像组合数把它“吸收”了一样,因此叫吸收恒等式。

两边同乘 \(m\) 可以得到一个当 \(m = 0\) 时也成立的形式:

\[m \dbinom{n}{m} = n \dbinom{n - 1}{m - 1} \]

此外,这个恒等式还有一个保持两边下指标相同的形式:

\[(n - m) \dbinom{n}{m} = n \dbinom{n - 1}{m} \]

可以在两次应用组合恒等式之间代入原式推导出这一结果:

\[\begin{aligned} (n - m) \dbinom{n}{m} &= (n - m) \dbinom{n}{n - m} \\ &= n \dbinom{n - 1}{n - m - 1} \\ &= n \dbinom{n - 1}{m} \end{aligned} \]

III. 加法公式(杨辉/帕斯卡恒等式)

\[\boxed{\binom{n}{m} = \binom{n-1}{m-1} + \binom{n-1}{m}} \]

使用组合意义证明:从 \(n\) 个物品中选择 \(m\) 个物品,有两类方案:要么选择最后一个物品,要么不选择最后一个物品。如果选择最后一个物品,那么还要剩下的 \((n - 1)\) 个物品中选 \((m - 1)\) 个,方案数为 \(\dbinom{n - 1}{m - 1}\);如果不选择最后一个物品,就要在剩下的 \((n - 1)\) 个物品中选择 \(m\) 个,方案数为 \(\dbinom{n - 1}{m}\)。因此,两者的和就是从 \(n\) 个物品中选 \(m\) 个物品的方案数 \(\dbinom{n}{m}\)

IV. 上指标求和

\[\boxed{\sum_{k = 0}^{n} \dbinom{k}{m} = \dbinom{n + 1}{m + 1}} \]

这个恒等式把一个组合数表示为下指标为常数的组合数之和。从杨辉三角上看,这相当于对某一列求前缀和。

使用组合意义证明:假设有一个集合 \(\{0, 1, \cdots, n\}\),我们想从中选出 \((m + 1)\) 个数,如果选出的数中最大值为 \(k\),就还要从 \(\{0, 1, \cdots, k - 1\}\)\(k\) 个数中选择 \(m\) 个数,方案数为 \(\dbinom{k}{m}\)

V. 二项式定理

\[\boxed{(x + y)^n = \sum_{k = 0}^{n} \binom{n}{k} x^{k}y^{n - k}} \]

二项式定理表明,把一个二项式 \(x + y\) 的幂展开,\(x\)\(y\) 的系数都是组合数。(这就是组合数又称为二项式系数的原因。)

该定理同样可以用组合意义证明:把乘积

\[\begin{matrix} \qquad \qquad \quad n \ \text{factors} \\ (x + y)^{n} = \overbrace{(x + y)(x + y) \cdots (x + y)} \end{matrix} \]

展开时,每一项都是 \(n\)\(x\)\(y\) 的积,即形如 \(x^{i}y^{j}\)。又由于每个括号提供一个因子,所以 \(i + j = k\),并且从 \(n\) 个括号中选择 \(k\)\(x\) 的方案数为 \(\dbinom{n}{k}\),因此 \(x^{k}y^{n - k}\) 的系数为 \(\dbinom{n}{k}\)

(需要说明的是,如果 \(n\) 不是非负整数,而是负数或者其它任意的实数,二项式定理也仍然成立。这时和式是无限的,因此必须保证 \(|x / y| < 1\) 以使得和式收敛。不过这不在本文讨论范围之内。)

二项式定理有两个重要的推论:当 \(x = y = 1\) 时有

\[\boxed{2^{n} = \sum_{k = 0}^{n} \dbinom{n}{k}} \]

这意味着第 \(n\) 行的组合数之和为 \(2^{n}\)。(遗憾的是,虽然我们有上指标求和公式,但下指标的和没有封闭形式——我们只能求出一整行的和,而不能求出一行的某个前缀的和。)

如果 \(x = -1\)\(y = 1\),那么

\[0 = \sum_{k = 0}^{n} (-1)^{k}\dbinom{n}{k} \]

也就是说同一行组合数的交错和为 \(0\)。换一个表示形式:

\[\sum_{k \ \text{is even}} \dbinom{n}{k} = \sum_{k \ \text{is odd}} \dbinom{n}{k} \]

也就是奇数项之和等于偶数项之和。

VI. 三项式恒等式

\[\boxed{\dbinom{n}{m} \dbinom{m}{k} = \dbinom{n}{k} \dbinom{n - k}{m - k}} \]

这个恒等式用来解决两个组合数相乘的问题。虽然它的右边仍然是两个组合数,但 \(m\) 只出现了一次。所以,当关于 \(m\) 求和时,右边的形式往往更方便。

简单地把式子拆开即可证明。

VII. 范德蒙德卷积

\[\boxed{\sum_{i = 0}^{n} \dbinom{n}{i} \dbinom{m}{k - i} = \dbinom{n + m}{k}} \]

使用组合意义证明:从 \(n\) 个男人和 \(m\) 个女人中选择 \(k\) 个人,有 \(\dbinom{n + m}{k}\) 种方法。而如果选择 \(i\) 个男人和 \((k - i)\) 个女人,就有 \(\dbinom{n}{i} \dbinom{m}{k - i}\) 种方法,对 \(i\) 求和就得到了所有的方案。

VIII. 对角线求和

\[\boxed{\sum_{k = 0}^{m} \dbinom{n + k}{k} = \dbinom{n + k + 1}{m}} \]

用加法恒等式逐步展开即可证明。

posted @ 2025-04-14 19:03  DengStar  阅读(40)  评论(0)    收藏  举报