组合数学(未完结)
组合数学
组合数学应该是 OI 中数学板块里内容最多,最重要的一部分了吧。感觉组合数学也是最有意思的。相信可以总结的点一定很多(确信)。希望我的总结不要又臭又长。
计数原理
加法原理
若完成一件事的方法有
乘法原理
若完成一件事需要
排列组合
排列数
从
组合数
从
基本性质
-
展开组合数公式即可。
-
证明:
从
个元素中取 个元素有两类方法:取 号元素和不取 号元素。若取
号元素,则需要在剩下 个元素中取 个,即 种;若不取
号元素,则需要在剩下 个元素中取 个,即 种。然后加法原理即可。
证毕。
这条性质同样也可以看做是杨辉三角。
-
证明:
从
个不同元素中取出若干个元素组成一个集合,有 类方法,分别是取出 个。由加法原理可知,共有 种方法。也相当于是
个元素中每个元素都可以取或者不去,方案数为 。二者相等。
证毕。
二项式定理
证明:
数学归纳法。
当
假设当
证毕。
组合数求和
-
对角线求和:
-
直线求和:
组合数求法
-
递推法
根据基本性质 2,通过杨辉三角递推求组合数。
时间复杂度:
。此方法主要适用于预处理。
代码实现:
C[0][0]=1;//upd on 2022.7.18:一般来说不会用到这个,但是我在某场模拟赛补题中因为这个 WA 75pts 了。 for (int i=1;i<=n;i++) for (int j=0;j<=i;j++) { if (i==1 || j==0) C[i][j]=1; else C[i][j]=(C[i-1][j]+C[i-1][j-1])%mod; }
-
乘法逆元
此方法主要用于结果要求模大素数时。比如我们要求
:因为
,所以我们可以预处理出来 以及 和 的逆元,然后三者相乘即为答案。时间复杂度:
。代码实现:
void init()//预处理 { jc[0]=jc[1]=inv[0]=inv[1]=in[1]=in[0]=1; for(int i=2;i<=n;i++) { jc[i]=jc[i-1]*i%mod;//阶乘 inv[i]=(mod-mod/i)*inv[mod%i]%mod;//inv[] 是逆元。 in[i]=in[i-1]*inv[i]%mod;//in[] 表示阶乘逆元。 } } int C(int n,int m){return jc[n]*in[m]%mod*in[n-m]%mod;}
-
质因数分解
因为
,所以可以对分子,分母快速分解质因数,在数组中保存各项质因子的质数。然后把分子,分母各个质因子的指数对应相减(把分母消去),最后把剩余质因子乘起来即可。时间复杂度:
。
Lucas 定理
若
也就是把
本来是不打算写证明的,因为这个证明也不需要掌握,但是我感觉它非常有意思,所以就把它写在这里吧。
证明:
咕咕咕……(组合数学完全整理完之前一定过来补上!)
证毕。
代码实现:
int lucas(int n,int m,int p)
{
if(m==0)return 1;
return (C(n%p,m%p,p)*lucas(n/p,m/p,p))%p;
}
可重集的排列数
可重集,指的是包含重复元素的广义集合。
可重集的组合数
设
设整数
证明:
原问题等价于求下列集合的数量:
原问题等价于
也可以看做总共有
而可重集
证毕。
不相邻的排列
证明:
插空法。利用逆向思维,先从
证毕。
错位排列
将
我们分两步考虑递推关系:
-
第一步,考虑第
个元素,把它放在在某一个位置,比如位置 ,一共有 种放法; -
第二步,考虑第
个元素,这时有两种情况:-
把它放到位置
,那么对于除 以外的 个元素,由于第 个元素放到了位置 ,所以考虑剩下 个元素的错排即可,有 种放法; -
第
个元素不放到位置 ,这时对于这 个元素的错排,有 种放法。
-
根据乘法原理和加法原理可知:
另外:
这一点是根据容斥原理推出来的。
也就是说,
注意,容斥原理是总方案数-不合法方案数,这里的“不是错排”就是“错排”的反义,所以不是错排的方案数就是不合法方案数。
错位排列前几项:
圆排列
考虑其中已经排好的一圈,从不同位置断开,变成不同的队列。所以有:
那么部分圆排列的方案数(即
另外,将
放球问题
最全面的放球问题请参考放球问题 学习笔记 - ACodinghusky - 博客园,这里只讨论最常见的 8 种情况。
在考虑这个问题之前,我们先解释一个问题:球同和球异,盒同和盒异到底有什么区别?
说实话,我其实刚开始一直是糊涂的,知道看到 dbxxx 的博客里面的一段话才理解:
球盒区别解释
假设n=3,m=2,对球编号 1,2,3:
为方便,规定类似于如下的表示:
{1, 2}, {3}
表示第一个盒子中有1,2两个球,第二个盒子中有3一个球而且无论十六种问题中哪一种,对于单个盒子而言,即使球有区别,盒子内部球的顺序永远只算一种情况。也就是说
{1, 2}, {3}
和{2, 1}, {3}
只能算作一种情况(无论 16 种问题的哪一个。)如果球有区别,盒也有区别,那么除了上一句说的情况外,其他所有的都各自算各自的情况。比如:
{1, 2}, {3}
,{3}, {1, 2}
,{1, 3}, {2}
这三种情况每一种都是不同的。如果球无区别,意味着将来自两个盒子的两个球进行交换是算作一种情况的。比如:
{1, 2}, {3}
和{1, 3}, {2}
是一种情况。如果盒无区别,意味着将任意两个盒子调换位置是算作一种情况的。比如:
{1, 2}, {3}
和{3}, {1, 2}
是一种情况。那么如果球和盒都没有区别……
{1, 2}, {3}
,{3}, {1, 2}
,{1, 3}, {2}
,{2, 3}, {1}
,{2}, {1, 3}
等都是一种情况。在球和盒都没有区别的模型下,还可以创造新的情况吗?
{}, {1, 2, 3}
,可以将一个盒子清空,这样就可以创造另一种情况了。同理,{1, 2, 3}, {}
和{}, {1, 2, 3}
是一种情况,因为盒子没有区别。在球和盒都没有区别的模型下,必须有空的集合才能有别的情况吗?当然不是。不妨考虑扩展到 4 个球。那么:
{}, {1, 2, 3, 4}
,{1}, {2, 3, 4}
,{1, 2}, {3, 4}
就是三种情况。
这里必须 %%% dbxxx,真的是把这个问题总结的非常全面详细。大家有兴趣可以去看看上面我放的他的博客。
假设有
-
球异,非空
-
盒同:
实际上就是第二类斯特林数,因此答案是
。第二类斯特林数的求法下面会提到,这里不做赘述。
-
盒异:
就相当于是计算出上述盒同的所有情况后给盒子编号,所以需乘上盒子的全排列。
所以答案是
。
-
-
球异,可空
-
盒异:
每个球都有
种放法,那么 个球就是 个 相乘,也就是 种放法。 -
盒同:
和 1 中的第一种情况的区别在于,盒子可以空放了。
那么枚举空盒个数累计到第二类斯特林数即可。因此,答案为
。
-
-
球同,非空
-
盒异:
隔板法。题目相当于把
个球分成 段,那么需要 个隔板。而
个球之间有 个缝隙。所以问题就转化为从 个缝隙中找到 个插进去。所以答案为
。 -
盒同:
请先移步到 4 第二种情况。在那一种情况基础之上,当遇到非空,我们强制给每个盒子一个球转化为可空,方案数就为
。
-
-
球同,可空
-
盒异:
同样和 3 中的第一种情况的区别在于,盒子可以空放了。
我们运用化归思想,把可空问题转化为非空问题。
先构造
求 盒和 3 中的第一种情况一样的问题。然后在所有方案中,我们给每个盒子里面去掉一个球,这样球的总数还是
个,方案也就转化成了可空的问题。也就是说可空的
球 盒问题,可以转化为不可空的 球 盒问题。那么最后答案就是
。怎么样?是不是很巧妙?
-
盒同:
实际上要求的是长度为
的有序数列个数,数列的元素和为 。
记 为划分方案数,有状态转移方程解释:考虑
个盒子中是否有空盒-
有空盒:新增一个空盒,贡献
; -
无空盒:向每个盒子放入一个球使其非空,贡献
;
-
-
两类特殊的数
卡特兰数
给定
的个数都不少于 1 的个数的序列的数量为:
证明:
令
所以此时,
同理,令
因此,以下两种序列构成了一个双射:
-
由
个 0 和 个 1 排成的,存在一个前缀 0 比 1 多的序列; -
由
个 0 和 个 1 排成的序列。
根据组合数的定义,后者显然有
综上,由
证毕。
推论
-
个左括号和 个右括号组成的合法括号序列的数量为 ; -
这 个自然数依次进栈,形成的合法的出栈序列的数量为 ; -
个节点构成的不同二叉树的数量为 ; -
凸
边形过顶点切分成 个三角形的不同方案数; -
在平面直角坐标系上,每一步只能向上或向右走,从
走到 并且除两个端点之外不接触直线 的路线数量是 ; -
给定
个 0 和 1,其中 个为 0,其余是 1 的 Catalan 数为:或者给定
个 0 和 1,其中 个为 0, 个为 1 的 Catalan 数为:物理意义:在平面直角坐标系上,每一步只能向上或向右走,从
走到 并且除两个端点之外不接触直线 的路线数量。
斯特林数
写在后面
post on 2022.4.19
组合数学这个我保证在完全结束这一板块的学习之前,就把所有该总结的都总结完。
一是这个版块的确是太重要了,另外咕咕咕并非一个好的习惯。
现在才有三千多字,后面可能会成倍成倍的往上增长(不是)。
感觉组合数学真的非常有意思,而且让人回味无穷(确信),但是这仍然改变不了我菜的事实。
说起来多多少少和组合数学有点渊源,毕竟,我在洛谷上发的第一篇题解就是组合数学,我 AC 的第一道黑题就是组合数学,我在洛谷上提交次数最多的题目也还是道组合数学。
艾教说,组合数学学好了整个 dp 就会串起来,就会变得非常强。
所以我会尽力把组合数学这块学好的。
To be continued……
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效