错位排列学习笔记

错排

百度一下:公式
百度一下:问题


  • 问题引入

对于有nn个标号为1n1\sim n的箱子和nn个标号为1n1\sim n的球,现在需要统计将所有的球放入箱子,每个箱子必须有且只有一个球,并且每个球的编号和装它的箱子的编号不一样的方案数。

假如n=3n=3,那么所有情况如下:

[1](2) [2](3) [3](1)[1](2)\ [2](3)\ [3](1)
[1](3) [2](1) [3](2)[1](3)\ [2](1)\ [3](2)

方括号为箱子,圆括号为球,数字为编号。


我们可以用递推的方式求出方案数。我们令f[i]f[i]表示当n=in=i的时候的答案,那么我们新加入一个箱子和球,就有两种情况:

  • 我们从原来的方案中拿出一个编号的箱子和球,有i1i-1种拿法,与这个新加入的交换,那么剩下的i2i-2个又成为了一个子问题,所以(i1)×f[i2](i-1)\times f[i-2]的贡献。

  • 我们还可以从原来的里面拿出一个编号的箱子(不拿球),那么有i1i-1种拿法,然后将新的装在这个箱子里,将新的箱子和剩下的又成为一个子问题,所以有(i1)×f[i1](i-1)\times f[i-1]的贡献。

总的来说,我们就得到了递推式:
f[i]=(i1)×(f[i1]+f[i2]) f[i]=(i-1)\times(f[i-1]+f[i-2])
其中边界条件为f[0]=1f[0]=1


在百度百科的讲解中,利用容斥原理可以得到通项公式如下:
f[n]=n!×(i=0n1i!×(1)i) f[n]=n!\times\left(\sum\limits_{i=0}^n\frac{1}{i!}\times(-1)^{i}\right)


例题:
IN Luogu

本题是Imagine\rm Imagine大佬出的,在此Orz\rm Orz并感谢他的讲解。

我们先算出刚好KK个配对的方案数量,然后乘以剩下的错排方案数,但是这个显然不是简单的错排了,因此不能直接套用公式。

前面的刚好KK个配对的就是:

  • kk排座位CnkC_n^k
  • kk对情侣CnkC_n^k
  • kk对每排可以交换坐2k2^k
  • kk排可以任意排列k!k!

所以前半部分的答案就为(Cnk)2×k!×2k(C_n^k)^2\times k!\times 2^k

那么对于错排部分,我们模仿错排递推的推导过程分类考虑,我们令g[n]g[n]nn对不匹配的方案数:

首先第一排坐两个不是情侣的人,不难发现那么可以有2n×(2n2)2n\times (2n-2)种选法,剩下只有n1n-1个座位,对于剩下的,我们考虑另外的两个就是与开始那两个坐在一起的另一半情侣,他们有两种方案:

  • 坐在一起:就是在剩下的n1n-1排中任选一排,且这个两个人可以交换,然后就转化为子问题g[n2]g[n-2],所以贡献为2×(n1)×g[n2]2\times (n-1)\times g[n-2]
  • 不坐在一起,我们就把他们又看作一个不能在一起的错排问题,于是贡献为g[n1]g[n-1]

和错排公式结合起来,所以这部分的方案数贡献为2n(2n2)(g[n1]+2(n1)g[n2])2n(2n-2)\left(g[n-1]+2(n-1)g[n-2]\right)

那么答案就是(Cnk)2×k!×2k×4n(n1)(g[n1]+2(n1)g[n2])(C_n^k)^2\times k!\times 2^k\times 4n(n-1)\left(g[n-1]+2(n-1)g[n-2]\right)

预处理阶乘和阶乘逆元还有gg函数,然后每次O(1)O(1)的回答即可。

复杂度为O(logMod+n+T)O(logMod+n+T)


End

posted @ 2018-10-18 13:52  VictoryCzt  阅读(301)  评论(0编辑  收藏  举报