1104 - Birthday Paradox
Sometimes some mathematical results are hard to believe. One of the common problems is the birthday paradox. Suppose you are in a party where there are 23 23 23 people including you. What is the probability that at least two people in the party have same birthday? Surprisingly the result is more than 0.5 0.5 0.5. Now here you have to do the opposite. You have given the number of days in a year. Remember that you can be in a different planet, for example, in Mars, a year is 669 669 669 days long. You have to find the minimum number of people you have to invite in a party such that the probability of at least two people in the party have same birthday is at least 0.5 0.5 0.5.
Input
Input starts with an integer T ( ≤ 20000 ) T (\leq 20000) T(≤20000), denoting the number of test cases.
Each case contains an integer n ( 1 ≤ n ≤ 1 0 5 ) n (1 \leq n \leq 10^5) n(1≤n≤105) in a single line, denoting the number of days in a year in the planet.
Output
For each case, print the case number and the desired result.
Sample Input
2
365
669
Output for Sample Input
Case 1: 22
Case 2: 30
题意
某星球一年有 n n n天,求一个集合中至少有多少人使得这些人至少有两个人生日是同一天的概率不低于 0.5 0.5 0.5
解法
另
P
P
P为
x
x
x人中至少有两个人生日是同一天的概率,那么有
P
=
1
−
A
n
x
n
x
≥
0.5
P=1-\frac{A_n^x}{n^x} \geq0.5
P=1−nxAnx≥0.5化简得
2
A
n
x
≤
n
x
2A_n^x \leq n^x
2Anx≤nx即
2
×
∏
i
=
0
x
−
1
n
−
i
≤
n
x
2\times \prod_{i=0}^{x-1}{n-i} \leq n^x
2×i=0∏x−1n−i≤nx两边取对数,得
log
2
+
∑
i
=
0
x
−
1
log
(
n
−
i
)
−
x
log
n
≤
0
\log2+\sum_{i=0}^{x-1}{\log (n-i) - x\log n} \leq 0
log2+i=0∑x−1log(n−i)−xlogn≤0
显然 随
n
n
n的增大
x
x
x是单调不减的,而且可以看到
n
=
2
n=2
n=2时
x
=
2
x=2
x=2,然后就可以
d
p
dp
dp了,本来只是想用这种做法打个前几项表,因为涉及
l
o
g
log
log相加减,可能会爆精度,没想到就直接过了
233
233
233,应该是因为
n
=
100000
n=100000
n=100000的时候答案也只有
372
372
372,所以没爆
代码
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
const double eps=1e-10;
int ans[maxn];
int main()
{
ans[1]=2;ans[2]=2;double cur=0;
for(int i=3;i<maxn;i++){
cur+=log(i);cur-=log(i-ans[i-1]);cur+=ans[i-1]*log(i-1);cur-=ans[i-1]*log(i);
ans[i]=ans[i-1];
while(cur>eps){
cur+=log(i-ans[i]);
cur-=log(i);
ans[i]++;
}
}
int t;scanf("%d",&t);
for(int i=1,n;i<=t;i++){
scanf("%d",&n);
printf("Case %d: %d\n",i,ans[n]-1);
}
}