错排问题的通项公式

我们定义错排数 dn 为满足下条件的排列的数目:排列的长度为 n 且不存在 i 使得 pi=i。在此避开对 d0 的讨论。它的递推式是 trivial 的:

dn=(n1)(dn1+dn2).(n>2)

并且显然有 d1=0,d2=1

直接通过递推式求解通项公式是困难的(对笔者来说),《具体数学》中给出了另一个办法如下。

根据容斥原理,我们可以直接写出 dn 的表达式:

dn=k=0n(1)k(nk)(nk)!

其中第 k 项表示:从 n 个位置中选出 k 个,钦定它们排列正确;剩下 (nk) 个可以随便乱排;最后乘上容斥系数 (1)k。(个人习惯:用 (mn) 表示 Cmn。)(当然,这个表达式也可以通过二项式反演得到。)

化简这个式子:

(1)dn=k=0n(1)k(nk)(nk)!=n!k=0n(1)kk!

观察后面的式子,可以联想到 ex 的 Maclaurin 展开式,即:

(2)ex=k0xkk!

(2) 式中取 x=1 ,得到:

(3)e1=k0(1)kk!

这与 (1) 的形式类似,于是我们希望用 (3) 来表示 (1) 。这引导我们分析两个式子的差的大小:

(4)n!k>n(1)kk!=n!k0(1)k+n+1(k+n+1)!=(1)n+1n+1k0(1)k(n+1)!(k+n+1)!=(1)n+1n+1(11n+2+1(n+2)(n+3))

括号中的量可以轻易地用裂项的方法得到:它介于 11n+2=n+1n+21 之间。于是, n!/edn 的差大约是 1/n;更精确地,它介于 1/(n+1)1/(n+2) 之间。

然而, dn 是一个整数。所以,如果 n>0,那么 dn 必定就是我们将 n!/e 四舍五入之后的整数。而一个简单的表示四舍五入的方法是加上 0.5 之后向下取整;于是,这样就求出了我们想要的封闭形式:

dn=n!e+12.

然而,这个公式并没有很大的实用价值,因为一般情况下 n! 的求值依然有着至少 O(n) 的复杂度。

posted @   Martin_MHT  阅读(318)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示