全错位排列

   问题描述:一个人写了n封不同的信及相应的n个不同的信封,他把这n封信都装错了信封,问都装错信封的装法有多少种?

通项公式:n!(1-1/1!+1/2!-1/3!+...+(-1)^n*1/n!)

递推公式:f(n) = (n - 1)(f(n - 1) + f(n - 2))

   证明:证明递推公式:用完全错排表示信与信封没有一个对应的状态,设n个信封的完全错排情况种数为f(n).

     现在假设n-1个信封已经完全错排,情况种数f(n - 1).那么将其原有任意的一条联系断开,只能与新增加的

     信和信封建立唯一的错位联系,这是第一种情况,共(n - 1)f(n - 1)种.还有另外一种情况, 如果原来的

     n - 1个信和信封并未完全错排,在只有一个对应的情况下,可以打断关系与新增加的信和信封建立唯一的

     错位联系,只有一个对应的情况是(n - 1)f(n - 2),相当于n - 2个错排加上任一个对应关系的情况.

     这样,最终:f(n) = (n - 1)(f(n - 1) + f(n - 2)).

  由完全构造法(不知道?当然,这是我发明的将复杂递推公式转化成通项公式的方法)即可有此推出通项公式.

应用举例:

            神、上帝以及老天爷

    Problem Description
    HDU 2006'10 ACM contest的颁奖晚会隆重开始了!
    为了活跃气氛,组织者举行了一个别开生面、奖品丰厚的抽奖活动,这个活动的具体要求是这样的:

    首先,所有参加晚会的人员都将一张写有自己名字的字条放入抽奖箱中;
    然后,待所有字条加入完毕,每人从箱中取一个字条;
    最后,如果取得的字条上写的就是自己的名字,那么“恭喜你,中奖了!”

    大家可以想象一下当时的气氛之热烈,毕竟中奖者的奖品是大家梦寐以求的Twins签名照呀!不过,正如所有试图设计的喜剧往往以悲剧结尾,这次抽奖活动最后竟然没有        一个人中奖!

    我的神、上帝以及老天爷呀,怎么会这样呢?

    不过,先不要激动,现在问题来了,你能计算一下发生这种情况的概率吗?

    不会算?难道你也想以悲剧结尾?!
 
 1 #include <iostream>
 2 #include <algorithm>
 3 #include <string.h>
 4 #include <stdio.h>
 5 //对于大数据,使用scanf,对于小数据,使用cin更方便
 6 using namespace std;
 7 
 8 int main()
 9 {
10     int n, i;
11     scanf("%d", &n);
12     int f[100] = {0, 0, 1};   //情况发生的个数
13     int fac[100] = {0, 1, 2}; //阶乘
14     for(i = 3; i < 100; i++){
15         fac[i] = fac[i - 1] * i;
16         f[i] = (i - 1) * (f[i - 1] + f[i - 2]);
17     }
18     while(n--)
19     {
20         scanf("%d", &i);
21         if(i > 10)
22             i = 10;
23         printf("%.2lf%%
", (double)f[i] * 100 / fac[i]);
24     }
25     
26     return 0;
27 }
原文地址:https://www.cnblogs.com/bmdx/p/3196649.html