【算法学习】组合数学

前言

本篇文章将跟随数学选择性必修三的步伐学习计数原理。

视频链接

这个也行oi-wiki

加法原理,乘法原理

分类加法计数原理:每一类相加起来。

分布乘法计数原理:每一步的方案乘起来。

排列

\(n\) 个元素中选 \(m\) 个元素组成排列的排列数(有序性)。

第一个位置有 \(n\) 个元素可选,第二个位置有 \(n-1\) 个元素可选,第 \(m\) 个位置有 \(n-m+1\) 个元素可选。

\[A_{n}^{m}=n\left(n-1\right)\left(n-2\right)\ldots\left(n-m+1\right)=\frac{n!}{\left( n-m\right)!} \]

组合

\(n\) 个元素中选 \(m\) 个元素合成一组的组数(无序性)。

因为组合是无序的可得:\(A_n^m=C_n^m\times A_m^m\)

由此可得:\(C_n^m=\frac{n!}{(n-m)!m!}\)

杂项:\(C_n^0=1,C_n^m=C_n^{n-m}\)

OI题

P6191 Bulls And Cows S

我们定义状态 \(f_i\) 为长度为 \(i\) 最后一个牛是公牛的方案数,那他可以从 \(f_{[1,i-k-1]}\) 转移过来,这个就可以用前缀和优化。

P1771 方程的解

\(x^x\) 可以直接用快速幂求得,剩下就是如何分配 \(a_i\) 使得和为 \(g(x)\),其实可以解释为 \(g(x)\) 分成 \(k-1\) 个部分,这就可以用插板法求得:

\[\binom{g(x)-1}{k-1} \]

因为要阶乘而数有点大所以要开高精度(高精不好的我默默流泪)。

P10592 BZOJ4361 isn

当一个序列删成非降序列的话那操作就要停止,所以我们要求的是最后一步刚好删成非降序列的操作数,但是这样做太复杂了,我们先不考虑停止操作,让他一直删下去。

这时我们就要知道长度为 \(i\) 的非降序列的数量然后才能计算答案,我们有 \(f_{i,j}\) 为第 \(i\) 个数长度为 \(j\) 的非降序列的长度,我们可以用树状数组优化,比如我们要求以 \(3\) 结尾的长度为 \(2\) 的非降子序列的数量,我们就用树状数组查询小于 \(3\) 的长度 \(1\) 的非降子序列的数量,这样计算的时间复杂度为 \(O(n^2\log n)\)

接下我我们要统计长度为 \(i\) 的非降序列的总数量,我们有:

\[g_i=\sum_{i=1}^{n}\sum_{j=i}^{n}f_{j,i} \]

现在知道数量如何计算方案数,对于删成一个长度为 \(i\) 的非降序列的方案数为 \((n-i)!\),即删除数的全排列。总的方案数为:

\[ans=\sum_{i=1}^n g_i\times (n-i)! \]

接下来加上停止操作,我们要排除不合法的方案,当我们删除最后一个数使得非降序列长度为 \(i\),我们是从 \(i+1\) 转移过来,但是如果 \(i+1\) 删掉最后一个数使得非降序列长度为 \(i+1\) 的话就会停止操作使得不会再向下传递使我们造成贡献,所以我们要容斥掉那一部分,总计算为:

\[ans=\sum_{i=1}^n g_i\times (n-i)!-g_{i+1}\times (n-i-1)!\times (i+1) \]

\(i+1\) 是因为我们有 \(i+1\) 个数可以作长度为 \(i\) 的非降序列的最后一个删的数。

posted @ 2025-07-21 00:23  sad_lin  阅读(51)  评论(0)    收藏  举报