hduoj2048 神、上帝以及老天爷
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个数字的排列,使所有的数字都不在自己所对应序号的位置上,这样的一个排列就称为原排列的一个错排,求所有可能的错排的个数。
分析
- d p [ n ] dp[n] dp[n]表示n个数字错排的方案数, d p [ n − 1 ] dp[n-1] dp[n−1]表示 ( n − 1 ) (n-1) (n−1)个数字错排的方案数;
- 假设对于第 M M M个位置的数字 m m m,首先取位置 K K K的元素放置,此时有 ( n − 1 ) (n-1) (n−1)种情况;
- 考虑第 K K K个位置的数字 k k k:如果 k k k放在第 M M M个位置,此时有 ( n − 2 ) (n-2) (n−2)个数字进行错排,方案数为 d p [ n − 2 ] dp[n-2] dp[n−2];如果 k k k不在第 M M M个位置,此时就是 ( n − 1 ) (n-1) (n−1)个数字进行错排,方案数为 d p [ n − 1 ] dp[n-1] dp[n−1];
- 综上所述,所有的情况就是 d p [ n ] = ( n − 1 ) ⋅ ( d p [ n − 1 ] + d p [ n − 2 ] ) dp[n]=(n-1)\cdot(dp[n-1]+dp[n-2]) dp[n]=(n−1)⋅(dp[n−1]+dp[n−2])。
#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;
}
博客围绕错排问题展开,以HDU抽奖活动无人中奖为例引出问题,即计算n个人抽奖都不中奖的概率。介绍了错排问题的定义,即n个数字排列使所有数字不在对应序号位置上。并通过分析得出错排方案数的递推公式dp[n]=(n - 1)⋅(dp[n - 1]+dp[n - 2])。
545

被折叠的 条评论
为什么被折叠?



