组合数学与计数(瞎写)

组合数学与计数

笔记,不含练习。

基本计数原理#

加法原理
乘法原理

组合数#

(nr)Cnr 表示组合数,从 n 个元素中选 r 个的方案数,不考虑顺序。(nr)=Cnr=n!r!(nr)!

类似的,Anr 表示排列数,从 n 个元素中选择 r 个的方案数,考虑顺序。Anr=n!(nr)!

一些性质#

对称恒等式

(nk)=(nnk)

吸收提取不等式

(nk)=nk(n1k1)

与下降幂结合

(nk)×km=(nmkm)×nm

加法归纳恒等式

(nk)=(n1k)+(n1k1)

二项式定理

(x+y)n=k(nk)xkyrk

下降幂转组合数

nk=(nk)k!

三项式版恒等式

(rm)(mk)=(rk)(rkmk)

范德蒙德卷积

i=0k(ni)(mki)=(n+mk)

插板法#

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

考虑拿 k1 块板子插入到 n 个元素两两形成的 n1 个空里面。
因为元素是完全相同的,所以答案就是 (n1k1)
本质是求 k 个未知数和为 n正整数解的组数。

允许每组为空?

考虑加入 k1 个元素,这样有 n+k1 个元素。考虑从中选 k1 个作为板子进行分隔。
答案即为 (n+k1k1)
本质是求 k 个未知数和为 n非负整数解的组数。

如果再扩展一步,要求对于第 i 组,至少要分到 aiain 个元素呢?

考虑先把下界补满,然后问题就转换为允许每组为空的了。
答案即为 (nai+k1k1)

二项式求导#

计算 k=1nk2(nk)

考虑 axn 的导数等于 anxn1

由二项式定理得:

(1+x)n=k=0nxk(nk)

两边同时求导:

n(1+x)n1=k=0nkxk1(nk)

两边同乘 x

nx(1+x)n1=k=0nkxk(nk)

两边同时求导:

n((1+x)n1+(n1)x(1+x)n2)=k=0nk2xk1(nk)

x=1 带入得到:

k=0nk2(nk)=n(n+1)2n2

组合数取模#

卢卡斯定理:

(nm)=(nmodpmmodp)(npmp)(modp)

例题#

n 个不同元素,选 r 个,每个可以选择多次(类似多重背包)。求方案数。

这个问题等价于 n 个未知数和为 r 的方案数。引用上面的结论即可。

n 个不同元素,选 r 个,选的元素不能相邻。

考虑空格的分配。
r 个元素,显然有 r+1 个空格(算上两边),其中,两头的两个的空格最少可以是 0 个格子,中间的空格最少是 1 个格子。
因为要选 r 个物品,所以有 nr 个格子是空格。
问题转化为 r+1 个未知数,和为 nr,其中 r1 个下界为 1,剩下的两个下界为 0
套用上面的公式,答案即为 (nr(r1)+(r+1)1(r+1)1)=(nr+1r)

k=0n(nk)2

考虑 (nk)=(nnk),那么上式变为 k=0n(nk)(nnk)
就相当于把 2n 个物品分成两段,枚举前面半段选多少,后面半段选多少。
显然等于 (2nn)

x 拆分为 n不同的组合数之和,求一组合法方案。

x=i=1k1(i0)+(xk+11)

比较 (n1m1)(n2m2) 的大小,n,m106

预处理阶乘的 log,比较 log 的大小。

错排#

Dn 表示 n 个元素错排的方案数。

如果 n=0,只能啥也不干,所以 D0=1

如果 n=1,没法错排,所以 D1=0

如果 n=2,只能交换两个元素,所以 D2=1

考虑加入第 n 个元素,假设放在了第 i 个位置。显然有 (n1)i 可选。

对于每个 i,考虑第 i 号元素放在哪。

  1. 放在 n 号位置。这样剩下的 (n2) 个元素错排即可。
  2. 不放在 n 号位置。因为 i 不能放在 n,而且因为原先的 i 位置被占用,就相当于没有,那么 n 号位置就相当于 i 号位置。这样 (n1) 个元素错排即可。

综上,Dn=(n1)(Dn1+Dn2)

斯特林数#

第二类#

{nm} 表示把 n 个元素划分成 m不可区分非空集合的方案数。

转移#

0 个东西放在 0 个集合里面只能啥也不干,所以 {00}=1

考虑加入一个元素。

如果这个元素放在一个独立的集合内,有一种方案,剩下的部分有 {n1m1} 种。

如果放在一个已有的集合内,有 k 种方案,剩下的部分有 {n1m1} 种方案。

所以:

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

第一类#

[nm] 表示把 n 个元素划分成 m不可区分非空轮换的方案数。

一个轮换就是一个首尾相接的环形排列。

我们可以写出一个轮换 [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]

转移#

0 个东西放在 0 个轮换里面只能啥也不干,所以 [00]=1

考虑加入一个元素。

如果这个元素放在一个独立的轮换内,有一种方案,剩下的部分有 [n1m1] 种。

如果放在一个已有的集合内,有 (n1) 种方案,剩下的部分有 [n1m1] 种方案。

所以:

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

通常幂和下降幂的转换#

下降幂转通常幂:

xn=k=0n(1)nk[nk]xk

通常幂转下降幂:

xn=k=0n{nk}xk

容斥#

通过集合交的大小,求出集合并的大小。

U 中元素有 n 种不同的属性,而第 i 种属性称为 Pi,拥有属性 Pi 的元素构成集合 Si,那么:

|i=1nSi|=m=1n(1)m1ai<ai+1|i=1mSai|

错排#

这里有 n 个条件,形如 i 在正确的位置上。

显然,错排方案数=全排列-有至少一个在正确的位置上的的方案数。

考虑如何求出有至少一个在正确的位置上的方案数。

考虑容斥。满足任意 k 个条件的方案数是:(nk)×(nk)!=n!k!,容斥系数为 k1

综上,错排方案数为:

D(n)=n!k=1n(1)k1n!k!=n!+k=1n(1)kn!k!=k=0n(1)kn!k!

但是这个式子就算预处理逆元都是 Θ(n) 的,而且 Θ(n) 的时间只能求一项,没啥用。

卡特兰数#

介绍#

以下问题属于Catalan数列:

  1. 2n 个人排成一行进入剧场。入场费 5 元。其中只有 n 个人有一张 5 元钞票,另外 n 人只有 10 元钞票,剧院无其它钞票,问有多少种方法使得只要有 10 元的人买票,售票处就有 5 元的钞票找零?
  2. 一位大城市的律师在她住所以北 n 个街区和以东 n 个街区处工作。每天她走 2n 个街区去上班。如果他从不穿越(但可以碰到)从家到办公室的对角线,那么有多少条可能的道路?
  3. 在圆上选择 2n 个点,将这些点成对连接起来使得所得到的 n 条线段不相交的方法数?
  4. 对角线不相交的情况下,将一个凸多边形区域分成三角形区域的方法数?
  5. 一个栈(无穷大)的进栈序列为 1,2,3,,n 有多少个不同的出栈序列?
  6. n 个结点可构造多少个不同的二叉树?
  7. n+1n1 构成 2na1,a2,,a2n,其部分和满足 a1+a2++ak0k=1,2,3,,2n)。对于 n,该数列为?

其对应的序列为:

H0 H1 H2 H3 H4 H5 H6
1 1 2 5 14 42 132

这就是卡特兰数列。

计算#

卡特兰数的递推式为:

Hn=i=0n1HiHni1(n2)

其中 H0=1H1=1

其他常见的公式有:

Hn=(2nn)n+1(n2,nN+)Hn={i=1nHi1Hnin2,nN+1n=0,1Hn=Hn1(4n2)n+1Hn=(2nn)(2nn1)

非降路径计数#

非降路径是指只能向上或向右走的路径。

  1. (0,0)(m,n) 的非降路径数等于 mxny 的排列数,即 (n+mm)
  2. (0,0)(n,n) 的除端点外不接触直线 y=x 的非降路径数:
    先考虑 y=x 下方的路径,都是从 (0,0) 出发,经过 (1,0)(n,n1)(n,n),可以看做是 (1,0)(n,n1) 不接触 y=x 的非降路径数。
    所有的的非降路径有 (2n2n1) 条。对于这里面任意一条接触了 y=x 的路径,可以把它最后离开这条线的点到 (1,0) 之间的部分关于 y=x 对称变换,就得到从 (0,1)(n,n1) 的一条非降路径。反之也成立。从而 y=x 下方的非降路径数是 (2n2n1)(2n2n)。根据对称性可知所求答案为 2(2n2n1)2(2n2n)
  3. (0,0)(n,n) 的除端点外不穿过直线 y=x 的非降路径数:
    用类似的方法可以得到:2n+1(2nn)
    如果要求只能在直线的下方和直线上走,则方案数是 1n+1(2nn),即卡特兰数。

问题#

有一个函数 f(i,j)=f(i1,j)+f(i,j1),f(0,0)=1,0ij,证明:f(n,n)=Catalan(n)

容易发现,f(i,j)=f(i1,j)+f(i,j1),0ij 就是求 (0,0) 走到 (i,j) ,始终在 y=x 下方和 y=x 上走的方案数的递推式。这个就是卡特兰数。

板子#

下降幂

int dpow(int a,int b){
	int ans=1;
	for(int i=0;i<b;i++)ans=ans*(a-i)%mod;
	return ans;
}

快速幂

int ksm(int a,int b){
	int ans=1;
	for(;b;b>>=1){
		if(b&1)ans=ans*a%mod;
		a=a*a%mod;
	}
	return ans;
}

逆元

int inv(int a){
	int ans=1;
	for(int i=mod-2;i;i>>=1){
		if(i&1)ans=ans*a%mod;
		a=a*a%mod;
	}
	return ans;
}

组合数

int C(int a,int b){
	return fact[a]*inv(fact[b])%mod*inv(fact[a-b])%mod;
}
posted @   洛谷Augury  阅读(78)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
more_horiz
keyboard_arrow_up light_mode palette
选择主题
menu
点击右上角即可分享
微信分享提示