LightOJ-1104 Birthday Paradox
题意
经典的生日悖论问题,现在假设一年有n
天,问一个生日聚会至少邀请多少人才能保证至少有两个人生日相同的概率不小于0.5
。
做法
首先我们通过样例大胆猜对于每个n
,答案应该很小。之后我们用dp
的方法求即可。
dp[i]
表示到i
个人出现两个人生日相同的概率,首先1-dp[i-1]
表示i-1
个人没出现两个人生日相同的概率,之后只要第i
个人生日和i-1
个人中的某一个相同即可,又因为i-1
个人的生日两两不同,所以第i
个人与i-1
个人中的某一个生日相同的概率为
i
−
1
n
\frac{i-1}{n}
ni−1,于是可以得到转移式:
d p [ i ] = ( 1 − d p [ i − 1 ] ) ∗ i − 1 n + d p [ i − 1 ] dp[i]=(1-dp[i-1])*\frac{i-1}{n}+dp[i-1] dp[i]=(1−dp[i−1])∗ni−1+dp[i−1]
最后当dp[i]
大于等于0.5
跳出即可,注意题目中邀请的人不算自己,所以要减去1
输出。
代码
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<math.h>
using namespace std;
const double eps = 1e-8;
int sgn(double x)
{
if(fabs(x)<eps) return 0;
if(x<0) return -1;
return 1;
}
int main()
{
int t;
scanf("%d",&t);
int cas=0;
while(t--)
{
int n;
int ans=1;
scanf("%d",&n);
double tmp=0;
double cc=0;
for(int i=2;;i++)
{
tmp=(1.0-cc)*(1.0*(i-1)/n);
cc=cc+tmp;
if(sgn(cc-0.5)>=0)
{
ans=i;
break;
}
}
printf("Case %d: %d\n",++cas,ans-1);
}
return 0;
}