【LightOJ 1104】Birthday Paradox(概率DP)
题目大意:
问一年n天的情况下,除自己外还要找几个人能满足至少两个人生日同一天的概率 >= 0.5
想了个预处理,被n <= 10^5吓到了……后来看他们做法才知道 降到0.5以下快的飞起……
找到公式就好搞了,要求在场至少两个人生日同一天的概率 >= 0.5,其实也是在场人生日都不同的概率 < 0.5。
那么令n为算上自己的人数,这样好列方程。
为
p=∑i=1kn−i+1n<0.5
k为总人数
每次读到n然后暴力从 nn 递减搞一下搞到第一个 < 0.5的位置 k-1即为答案
搞了个预处理……从n-1转移过来
代码如下:
#include <iostream>
#include <cmath>
#include <vector>
#include <cstdlib>
#include <cstdio>
#include <climits>
#include <ctime>
#include <cstring>
#include <queue>
#include <stack>
#include <list>
#include <algorithm>
#include <map>
#include <set>
#define LL long long
#define Pr pair<int,int>
#define fread(ch) freopen(ch,"r",stdin)
#define fwrite(ch) freopen(ch,"w",stdout)
using namespace std;
const int INF = 0x3f3f3f3f;
const int msz = 100000;
const int mod = 1e9+7;
const double eps = 1e-8;
int dp[msz+1];
double ned[msz+1];
double Pow(double a,int b)
{
double ans = 1;
while(b)
{
if(b&1) ans = ans*a;
b >>= 1;
a *= a;
}
return ans;
}
void init()
{
dp[1] = 2;
dp[2] = 2;
ned[3] = 1.0*2/3/3;
dp[3] = 3;
for(int i = 4; i <= msz; ++i)
{
ned[i] = ned[i-1]*Pow((i-1)*1.0/i,dp[i-1]);
dp[i] = dp[i-1]+1;
while(ned[i]*i/(i-dp[i]+1) < 0.5)
{
ned[i] = ned[i]*i/(i-dp[i]+1);
dp[i]--;
}
}
}
int main()
{
int t,n;
init();
scanf("%d",&t);
for(int z = 1; z <= t; ++z)
{
scanf("%d",&n);
printf("Case %d: %d\n",z,dp[n]-1);
}
return 0;
}
#include <iostream>
#include <cmath>
#include <vector>
#include <cstdlib>
#include <cstdio>
#include <climits>
#include <ctime>
#include <cstring>
#include <queue>
#include <stack>
#include <list>
#include <algorithm>
#include <map>
#include <set>
#define LL long long
#define Pr pair<int,int>
#define fread(ch) freopen(ch,"r",stdin)
#define fwrite(ch) freopen(ch,"w",stdout)
using namespace std;
const int INF = 0x3f3f3f3f;
const int msz = 100000;
const int mod = 1e9+7;
const double eps = 1e-8;
int main()
{
//fread("in.in");
//fwrite("");
int t,n;
scanf("%d",&t);
for(int z = 1; z <= t; ++z)
{
scanf("%d",&n);
double tmp = 1;
int ned = 1;
while(tmp*(n-ned)/n > 0.5)
{
tmp = tmp*(n-ned)/n;
ned++;
}
printf("Case %d: %d\n",z,ned);
}
return 0;
}