问题描述:一个人写了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签名照呀!不过,正如所有试图设计的喜剧往往以悲剧结尾,这次抽奖活动最后竟然没有 一个人中奖!
我的神、上帝以及老天爷呀,怎么会这样呢?
不过,先不要激动,现在问题来了,你能计算一下发生这种情况的概率吗?
不会算?难道你也想以悲剧结尾?!
为了活跃气氛,组织者举行了一个别开生面、奖品丰厚的抽奖活动,这个活动的具体要求是这样的:
首先,所有参加晚会的人员都将一张写有自己名字的字条放入抽奖箱中;
然后,待所有字条加入完毕,每人从箱中取一个字条;
最后,如果取得的字条上写的就是自己的名字,那么“恭喜你,中奖了!”
大家可以想象一下当时的气氛之热烈,毕竟中奖者的奖品是大家梦寐以求的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 }