题目链接http://blog.youkuaiyun.com/u014362024
题目就是告诉我们每天都只有两个人相遇,如果是人和人或者吸血鬼和吸血鬼碰面了,没啥事可以发生,但是如果任何吸血鬼相遇了,人有p的概率变成吸血鬼,问全部变成吸血鬼的天数的数学期望。
一想就可以发现这是一个标准的概率DP问题 = =,如果不懂,可以自行百度概率DP,会有很多题可供做。
dp[i]表示的是吸血鬼有i个时的期望。然后进行逆推,最后输出 dp[1]即可。至于状态转移方程:dp[i] = (dp[i+1]+1)*p1 + p2 *(dp[i]+1)(p1+p2=1)
(p1是i个吸血鬼再增加一个的概率,也就是说一个人喝一个吸血鬼相遇且变身的概率)
现在解释下其中的意思,p1*(dp[i+1]+1)表示接下来一天增加了一个吸血鬼得到的期望,然后p2*(dp[i]+1)表示未增加吸血鬼,显然p2=1-p1,然后dp[i]就可以转移了。
整理可以得到 dp[i] = (1.0)*(p`*dp[i+1]+1)/p`; p` =p * i*(n-i)/c(c,2);表示人和吸血鬼相遇切变身的概率,也就是p1。至于+1是因为天数增加了1。
AC代码如下:#include<iostream> #include<cstdio> using namespace std; #define mxn 100007 double dp[mxn]; int main() { int t; scanf("%d",&t); while(t--) { int n; double p; scanf("%d%lf",&n,&p); dp[n] = 0 ; for(int i = n-1 ; i > 0 ; --i) { double k1 = (double) n * ( n-1 ) /2; double k2 = (double) i * (n-i); double p3 = (double) p*k2/k1; //dp[i] = (dp[i+1] + 1)*p2 + p1*(dp[i] + 1)(p1+p2==1) dp[i] = (1.0)*(p3 * dp[i+1]+1)/p3; } printf("%.3lf\n",dp[1]); } }