组合数学

基本公式

二项式定理:

(a+b)n=i=0n(ni)aibni

其中 (ni) 成为二项式系数


多重集排列

N!i=1kni!

这道题 就是一个典型应用
对于 n 维空间里从 (1,1,,1) 走到 (n1,n2,,nk) 的方案数为多重集排列,
特殊地,二维空间内为 (x+yx)


多重集的组合

用于求解方程 i1nxi=m 非负整数解的个数,其中 xi<=limi

当任意 limi>=m 时,答案为 (n+m1n1)

否则运用容斥:

理解是所有未知数都满足限制的方案数等于总方案数-一个不满足的+两个不满足的……以此类推
一个未知数不满足的时候是取值大于等于 limi+1 的时候
则答案为

(1)k(n+m1i=1k(limi+1)n1)


不相邻排列

1n 中选择 k 个不相邻的方案数:

(nk+1k)

证明:
首先从 n 中选出 k1 个作为作为隔板,剩下 nk+1 个选出 k 作为最终选定数,即上式为答案,因为可以发现将 k1 个数放回一定可以对一一种合法方案


错排序列

求解 n 个数都不放在原来的位置上的方案数
设为 Dn,考虑递推:

Dn=(n1)(Dn1+Dn2)

当一个新的数来的时候,如果前 (n1) 已经错排,任意交换一个即符合
如果其中有 n2 个错拍,和另一个放置正确的交换也满足条件,而放置正确的数有 n1 种情况


C. 你猜是不是找规律

有时候 dp 时把错排放进状态可以有效避免重复问题


圆排列

n 个数中选出 m 个排成圆环的方案数为:

n!m(nm)!

特殊地选出 n 个数的圆环方案数为 (n1)!


一些有用的恒等式

i=0n(1)i(ni)=[n=0]

二项式定理的特殊形式

i=0m(ni)(mmi)=(m+nm)

范徳蒙恒等式,比较常用,比如这道题,详细题解下面写
上面的式子变形为:

i=0n(ni)2=(2nn)

i=0ni(ni)=n2n1

l=0n(lk)=(n+1k+1)

上式组合意义理解:n+1 个物品中选择 k+1 个,最后一个选第 l+1 个,剩下的 k 个从 l 个物品中选

(nr)(rk)=(nk)(nkrk)

上式很容易用组合意义证明

i=0n(nii)=Fibn+1


实现方式

对于组合数 (nm) 的求解根据数据范围的不同分为一下几种:

  • 方法一:暴力拆分——m 范围很小

暴力枚举 n 的下降幂,暴力或存储 m 阶乘,复杂度 O(m)

  • 方法二:预处理阶乘和逆元——n 范围小且 m 范围大

这种处理方式比较常用,递推出 n 值域范围的阶乘及其逆元,逆元递推式为 invi=invi+1(i+1),处理复杂度 O(n),调用 O(1)

  • 方法三:杨辉三角递推——nm 的范围都适中

根据 (ij)=(i1j)+(i1j1) 递推,预处理复杂度 O(n2),调用 O(1)

  • 方法四:卢卡斯公式——n 的范围很大且模数较小

通过公式 (nm)=(n%pm%p)(n/pm/p) 快速降低次数,并处理模数范围内阶乘即逆元求解
注意这种方式求解会出现 n<m 的情况,需要特判为 0

  • 方法五:分解质因数——没有模数或模数非质数

如果 m2 能承受可以对分子分母各 m 个数两两求 gcd 并约分,这时分母一定约为 1

也可以用类似线性筛的方式筛出每个质因子在分子分母各出现多少次然后约分

posted @   y_cx  阅读(174)  评论(0编辑  收藏  举报
(评论功能已被禁用)
编辑推荐:
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
点击右上角即可分享
微信分享提示