👉 “Offer 驾到,掘友接招!我正在参与2022春招打卡活动点击查看 活动详情。
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个数字错排的方案数,表示个数字错排的方案数;
- 假设对于第个位置的数字,首先取位置的元素放置,此时有种情况;
- 考虑第个位置的数字:如果放在第个位置,此时有个数字进行错排,方案数为;如果不在第个位置,此时就是个数字进行错排,方案数为;
- 综上所述,所有的情况就是。
#include<iostream>
#include<cstring>
#include<stack>
#include<queue>
#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
const int MAXN = 1e6 + 50;
const int MOD = 1e9 + 7;
const double eps = 1e-9;
const int INF=0x3f3f3f3f;
#define PI acos(-1)
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define mem(a,b) memset(a,b,sizeof(a))
#define rep(i,x) for(int i=0;i<x;++i)
#define UP(i,x,y) for(int i=x;i<=y;i++)
#define DOWN(i,x,y) for(int i=x;i>=y;i--)
const int N = 21;
int C,n; LL dp[N],f[N];
void Init(){
dp[0] = 0; dp[1] = 0; dp[2] = 1;
UP(i,3,N) dp[i] = (i - 1) * (dp[i-1] + dp[i-2]);
f[0] = f[1] = 1;
UP(i,2,N) f[i] = i * f[i-1];
}
int main(){
Init();
scanf("%d",&C);
while(C--){
scanf("%d",&n);
double p = dp[n] * 1.0 / f[n] * 100;
printf("%.2f%%\n", p); //不要用%lf输出double类型 输出%号记得%%
}
return 0;
}