错排公式简单应用

神、上帝以及老天爷

Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other)
Total Submission(s) : 5   Accepted Submission(s) : 3

Font: Times New Roman | Verdana | Georgia

Font Size:

Problem Description

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

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

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

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

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

不会算?难道你也想以悲剧结尾?!

Input

输入数据的第一行是一个整数C,表示测试实例的个数,然后是C 行数据,每行包含一个整数n(1<n<=20),表示参加抽奖的人数。

Output

对于每个测试实例,请输出发生这种情况的百分比,每个实例的输出占一行, 结果保留两位小数(四舍五入),具体格式请参照sample output。

Sample Input

1
2

Sample Output

50.00%
关键是推公式此题相似于装信封问题:
[问题描述]某人写了n封信和n个信封,如果所有的信都装错了信封。求所有的信都装错信封共有多少种不同情况。 
 [问题分析]
 1、当有N封信的时候,前面N-1封信可以有N-1或者N-2封错装;
 2、前者,对于每一种错装,可以从N-1封信中任意取一封和第N封错装,故=F(N-1)*(N-1);
 3、后者,只能是没装错的那封信和第N封信交换信封,没装错的那封信可以是前面N-1封信中的任意一个,故= F(N-2) (N-1)

得到如下递推公式:

 基本形式:f[1]=0;   f[2]=1 递归式:f[n]= (n-1)*( f[n-1] + f[n-2])

 

有了这道题的基础此题便相当简单了
AC代码:
#include<stdio.h>
__int64 lmx(__int64 n)
{
 if(n==1)  return 0;
 if(n==2)  return 1;
 else return (lmx(n-1)+lmx(n-2))*(n-1);
}
__int64 fan(__int64 n)
{
 if(n==0||n==1)  return 1;
 else return fan(n-1)*n;
}
int main()
{
__int64 t,n;
scanf("%I64d",&t);
while(t--)
{
 scanf("%I64d",&n);
 printf("%.2lf",(double)lmx(n)/fan(n)*100);
 puts("%");
}
 return 0;
}
posted @ 2012-10-28 13:23  forevermemory  阅读(360)  评论(0编辑  收藏  举报