您的位置:首页 > 其它

zoj 3351 Bloodsucker(概率 dp)

2013-08-24 15:30 483 查看
题目:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=4530

dp[i]表示现在存在i个吸血鬼要达成目标(全为吸血鬼)天数的数学期望
假如现在再增加一天,这一天可能会增加一个吸血鬼,
p1*(dp[i+1]+1)表示接下来的一天增加了一个吸血鬼,
所以为(dp[i+1]+1),
还有一种可能就是没有增加吸血鬼,概率自然是(1-p1)
dp[i]+1表示接下来的一天没有增加吸血鬼,但向后推移了一天
因此dp[i]这个状态可以转移到
dp[i+1]+1,概率为p1
dp[i]+1 概率为(1-p1)
所以dp[i]=(dp[i+1]+1)*p1+(dp[i]+1)*(1-p1);
p1是有i个吸血鬼再增加一个的概率
就是说一个人和一个吸血鬼相遇,且人成功变成吸血鬼的概率
为(n-i)*i*p/(C(n,2)),即2*(n-i)*i*p/((n-1)*n)

dp[i]=(dp[i+1]+1)*p1+(dp[i]+1)*p2

移项后化简得: p1*dp[i]=dp[i+1]*p1+1

#include <iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<stack>
#include<queue>
#include<iomanip>
#include<cmath>
#include<map>
#include<vector>
#include<algorithm>
using namespace std;

double d[110000];
int main()
{
int i,j,t,n;
double p;
cin>>t;
while(t--)
{
cin>>n>>p;
d
=0;
for(i=n-1; i>=1; i--)
{
double s1,s2,p1;
s1=(double)n*(n-1)/2;
s2=(double)i*(n-i);
p1=s2/s1*p;
d[i]=(d[i+1]*p1+1)/p1;
}
printf("%.3lf\n",d[1]);
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: