ZOJ3551 Bloodsucker(概率dp)

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=4530


Bloodsucker

Time Limit: 2 Seconds       Memory Limit: 65536 KB

In 0th day, there are n-1 people and 1 bloodsucker. Every day, two and only two of them meet. Nothing will happen if they are of the same species, that is, a people meets a people or a bloodsucker meets a bloodsucker. Otherwise, people may be transformed into bloodsucker with probability p. Sooner or later(D days), all people will be turned into bloodsucker. Calculate the mathematical expectation of D.

Input

The number of test cases (TT ≤ 100) is given in the first line of the input. Each case consists of an integer n and a float number p (1 ≤ n < 100000, 0 < p ≤ 1, accurate to 3 digits after decimal point), separated by spaces.

Output

For each case, you should output the expectation(3 digits after the decimal point) in a single line.

Sample Input
1
2 1

Sample Output
1.000


题意:总共有n个人,刚开始有1个是吸血鬼,每天有两个人会相遇。

如果是人碰到人或者吸血鬼碰到吸血鬼就没有任何事发生;

如果人碰到吸血鬼,那么人有p的概率被转化成吸血鬼。

问所有人都转化成吸血鬼的天数的数学期望。


概率dp的问题。

设数组dp[i]表示有i个吸血鬼时将人全部转化成吸血鬼所需天数的数学期望。初始状态dp[n]=0。

分析可以得出状态转移方程:dp[i]=(dp[i+1]+1)*p3+(dp[i]+1)*(1-p3);

其中p3表示人与吸血鬼相遇且被转化的概率(相遇概率为p2/p1=(i*(n-i))/(n*(n-1)/2),转化概率为p*p2/p1)

(dp[i+1]+1)*p3表示人被转化成吸血鬼的期望,(dp[i]+1)*(1-p3)表示没有被转化成吸血鬼的期望。

最后输出dp[1],即为1个吸血鬼时把所有人转化成吸血鬼所需天数的数学期望。


#include <iostream>
#include <cstdio>
using namespace std;

int n;
double p,dp[100005];

int main()
{
    int T;
    scanf("%d",&T);
    while (T--)
    {
          scanf("%d%lf",&n,&p);
          dp[n]=0.0;
          for (int i=n-1;i>=1;--i)
          {
              double p1=(double)n*(n-1)/2;//表示C(n,2),n个人中选出2个人相遇的情况总数
              double p2=(double)i*(n-i);//表示一个是人一个是吸血鬼的情况总数
              double p3=p*p2/p1;//人遇到吸血鬼并被转化的概率
              //dp[i]=(dp[i+1]+1)*p3+(dp[i]+1)*(1-p3);
              dp[i]=(dp[i+1]*p3+1)/p3;//化简后的状态转移方程
          }
          printf("%.3lf\n",dp[1]);//dp[1]即为所求答案
    }
    return 0;
}


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值