zoukankan      html  css  js  c++  java
  • 错排公式的证明与实现

      所谓错排公式就是说给你一个序列,这个序列有n个数,然后要求这个序列的排列中有几个满足每个元素都不在原来的位置。这个是直接有一个地推关系的:f[n]=(n-1)*(f[n-1]+f[n-2])。证明如下:

      首先我们知道f[1]=0,f[2]=1.然后当n大于等于三的时候我们考虑他们之间的关系。将各个元素标号为1到n。那么我们考虑第n个元素,它的能力在于是将自己与前面的一个换位置,也就是说它的前面可以是已经完成的错排或者是有一个元素没有错排。那么有两种情况:

    1、前面有一个元素在本身的位置,这时最后一个元素必须选择同他交换。没装错的可能是任意的一个,也就是有(n-1)*f[n-2]种

    2、前面的已经排好了,这是最后一个可以随意交换,也就是(n-1)*f[n-1]

    代码很简单,用递归写,但是还是贴一下吧

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cstdio>
     4 #include<queue>
     5 #include<cstring>
     6 #include<cmath>
     7 using namespace std;
     8 long long f[95];
     9 int main()
    10 {
    11     f[1]=0;
    12     f[2]=1;
    13     for(int i=3;i<=20;i++){
    14         f[i]=(f[i-1]+f[i-2])*(i-1);
    15     }
    16     int n;
    17     while(scanf("%d",&n)==1){
    18         printf("%lld
    ",f[n]);
    19     }
    20     return 0;
    21 }

       另外错排还有一个通项公式 f(n) = n![1-1/1!+1/2!-1/3!+……+(-1)^n*1/n!]。这个公式有两个解释,首先是它可以从递归式直接推出来;第二种方法是采用容斥定理证明。这里不赘述了。

    如果你觉得内容对你有帮助,请点个赞

    知识共享许可协议
    本作品采用知识共享署名-非商业性使用-相同方式共享 2.5 中国大陆许可协议进行许可。
  • 相关阅读:
    为什么编程是独一无二的职业
    TSQL 编程规范
    Windows实战Git环境配置msysGit+TortoiseGit
    Linux环境下Socket编程
    数据持久化
    Javascript类的定义和引用
    详解C中volatile关键字
    ACM HDU 1040 As Easy As A+B
    ACM POJ 1753Flip Game
    ACM HDU 1017 A Mathematical Curiosity
  • 原文地址:https://www.cnblogs.com/MrLJC/p/3460604.html
Copyright © 2011-2022 走看看