HDU2048神、上帝以及老天爷

神、上帝以及老天爷

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 29703    Accepted Submission(s): 12256


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%
 
省题:
题目中要求求每个人拿到的都不是写自己名字的概率;可知,改题为典型的全错排公式是组合数学中的经典问题,可参考俞勇的《ACM国际大学生程序设计竞赛--知识与入门》中,组合数学的排列问题;可以得到其递推全错排列公式为 : D(n) = (n-1)*(D(n-1)+D(n-2));

分析:
如果同学不知道,旁边也没有资料可以更好的理解,其实可以自己推导下:
当 n=1 的时候也就是说只有一个人的时候,那么他一定可以拿到写了自己的名字的纸条;
当 n=2 的时候(为了方便起见我们给这两个人编号为 a,b,)则他们的名字为 a,b 当纸条进入纸箱又被人抽中的时候,可以得到 所有的可能为 
                           a,b     b,a   那么全部都错排的其实就是 b,a了,个数为 1;
当 n=3 的时候  有 a,b,c   a,c,b  b,a,c   b,c,a  c,a,b   c,b,a     6种排列方式 那么与原排列(a,b,c)没有任何一个位置重合的就是  (b,c,a)和(c,a,b)两组了  可以推得全错排个数为 2;
同理可以推得 当 n=4 的时候 全错排的个数为 9;
当 n=5 的时候全错排个数为 44;
由此可以推得全错排个数的递推公式为  D(n) = (n-1)*(D(n-1)+D(n-2));

推出了全错排个数的递推公式,那么这种全错排发生的概率就可以求得了 :
P=概率发生的容量 / 事件的总容量;
也就是 P=全错排个数 / 总的排列个数; 

给出代码:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
int main()
{
	long long  f[21], sum;
	int i, t, n;
	f[1] = 0; f[2] = 1;
	for (i = 3; i<21; i++)//错排!
		f[i] = (i - 1)*(f[i - 1] + f[i - 2]);//错排公式;
	scanf("%d", &t);
	while (t--)
	{
		scanf("%d", &n);
		sum = 1;
		for (i = 1; i <= n; i++)//N个员工的所写名字的被拿到的可能的全排列;
			sum *= i;
		printf("%.2lf%%\n", f[n] * 100.0 / sum);//用全排列个数除以错排的个数得到  错排的概率;

	}

	return 0;
}


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值