zoj 3351 Bloodsucker(概率 dp)

题目: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[];
int main()
{
int i,j,t,n;
double p;
cin>>t;
while(t--)
{
cin>>n>>p;
d[n]=;
for(i=n-; i>=; i--)
{
double s1,s2,p1;
s1=(double)n*(n-)/;
s2=(double)i*(n-i);
p1=s2/s1*p;
d[i]=(d[i+]*p1+)/p1;
}
printf("%.3lf\n",d[]);
} return ;
}
上一篇:1088. [SCOI2005]扫雷Mine【网格DP】


下一篇:ZOJ3551 Bloodsucker(概率dp)