错排问题(在程序中的应用)

在百度百科中, 对错排问题有如下描述:

当n个编号元素放在n个编号位置,元素编号与位置编号各不对应的方法数用M(n)表示,那么M(n-1)就表示n-1个编号元素放在n-1个编号位置,各不对应的方法数,其它类推.

 

  第一步,把第n个元素放在一个位置,比如位置k,一共有n-1种方法;

 

  第二步,放编号为k的元素,这时有两种情况.1,把它放到位置n,那么,对于剩下的n-2个元素,就有M(n-2)种方法;2,不把它放到位置n,这时,对于这n-2个元素,有M(n-1)种方法;

 

  综上得到

 

  M(n)=(n-1)[M(n-2)+M(n-1)]

 

  特殊地,M(1)=0,M(2)=1

 

  下面通过这个递推关系推导通项公式:

 

  为方便起见,设M(k)=k!N(k), (k=1,2,…,n)

 

  则N(1)=0,N(2)=1/2

 

  n>=3时,n!N(n)=(n-1)(n-1)!N(n-1)+(n-1)!N(n-2)

 

  即 nN(n)=(n-1)N(n-1)+N(n-2)

 

  于是有N(n)-N(n-1)=-[N(n-1)-N(n-2)]/n=(-1/n)[-1/(n-1)][-1/(n-2)]…(-1/3)[N(2)-N(1)]=(-1)^n/n!

 

  因此

 

  N(n-1)-N(n-2)=(-1)^(n-1)/(n-1)!

 

  N(2)-N(1)=(-1)^2/2!

 

  相加,可得

 

  N(n)=(-1)^2/2!+…+(-1)^(n-1)/(n-1)!+(-1)^n/n!

 

  因此

 

  M(n)=n![(-1)^2/2!+…+(-1)^(n-1)/(n-1)!+(-1)^n/n!]

 

  可以得到

 

  错排公式为M(n)=n!(1/2!-1/3!+…..+(-1)^n/n!)

 

 

从这一个问题, 我们发现, 使用递推的思想很容易证明错排问题, 在百科之中, 对M(n-1)描述的不是特别清晰, 在这里, 根据自己的理解, 简要分析一样, 当n元素位置不放在k元素的位置的时候, 我们进行下面分析的时候, 可以吧k元素的位置看做是n元素的位置, 这样, 我们下一步要做的就是分析包括n在内的M(n-1)种可能。

  当我们推到出来递推公式, 这个在程序上的问题只是解决了一半, 下面, 要转化递推公式为通项公式, 这是一个关键的一步, 因为, 用递归完成非log数量级的问题, 真的很不划算的, 至于通项公式的求解过程可以参见百科。

 下面是相关的问题:

        装错信封问题

        1)同室四人各写一张贺年卡,先集中起来,然后每人从中拿一张别人送出的贺年卡.则四张贺年卡的不同分配方式有[ ]
       A.6种 B.9种 C.11种 D.23种
      2)有5个客人参加宴会,他们把帽子放在衣帽寄放室内,宴会结束后每人戴了一顶帽子回家.回家后,他们的妻子都发现他们戴了别人的帽子.问5个客人都不戴自己帽子的戴法有多少种?
     上述两个问题,实质上是完全一样的.是被著名数学家欧拉(Leonhard Euler,1707-1783)称为“组合数论的一个妙题”的“装错信封问题”的两个特例.“装错信封问题”是由当时最有名的数学家约翰•伯努利(Johann Bernoulli,1667-1748)的儿子丹尼尔•伯努利(DanidBernoulli,1700-1782)提出来的,大意如下:
      一个人写了n封不同的信及相应的n个不同的信封,他把这n封信都装错了信封,问都装错信封的装法有多少种?

当然, 自己第一次接触错排问题的时候, 也是AC了一个有关装错信封的问题。

 

  

posted @ 2012-07-31 11:24  黑色包裹  阅读(367)  评论(0编辑  收藏  举报