HDU 4089:Activation

Activation

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=4089

题意:

有个人在排队注册游戏账号,这整个队列共有N个人并且他目前位于第M个位置,因为官网的服务器不大好,所以随时有可能会崩溃,在此之前每个位于队列第一个位置的人都会面临四个随机事件:

    1、注册失败,队列保持不变  概率为p1 

    2、注册失败,走到队列尾部  概率为p2

    3、注册成功,离开队列    概率为p3

    4、服务器崩溃了           概率为p4

求在服务器奔溃的时候此人在队列中的位置大于等于k的概率 

 

题解:

设dp[i][j]为当队列中人数为i且此人位于第j位时达到目标状态的概率,则dp[n][m]即所求答案

则可以推出

  dp[i][j]=p1*dp[i][j]+p2*dp[i][i]+p4                 j==1

  dp[i][j]=p1*dp[i][j]+p2*dp[i][j-1]+p3*dp[i-1][j-1]+p4  1<j<=k

  dp[i][j]=p1*dp[i][j]+p2*dp[i][j-1]+p3*dp[i-1][j-1]      k<j<=i

设p=p2/(1-p1)则可化简得

  dp[i][j]=p*dp[i][i]+p4/(1-p1)                          j==1

  dp[i][j]=p*dp[i][j-1]+(p3*dp[i-1][j-1]+p4)/(1-p1)        1<j<=k

  dp[i][j]=p*dp[i][j-1]+(p3*dp[i-1][j-1])/(1-p1)              k<j<=i

迭代可得dp[i][i],再依次递推即可,求解过程中注意分母为0的情况

      

代码

 

#include<stdio.h>
#include<math.h>
double dp[2001][2001],c[2001];
int main()
{
  int n,m,k;
  double p,p1,p2,p3,p4,km,f;
  while(~scanf("%d%d%d%lf%lf%lf%lf",&n,&m,&k,&p1,&p2,&p3,&p4))
  {
    if(fabs(1.0-p1-p2)<1e-9)
    {
      puts("0.00000");
      continue;
    }
    p=p2/(1-p1),c[0]=1.0;
    for(int i=1;i<=n;++i)
    c[i]=c[i-1]*p;
    for(int i=1;i<=n;++i)
    {
      km=p4/(1-p1)*c[i-1];
      for(int j=1;j<=i;++j)
      {
        if(1<j&&j<=k)f=(p3*dp[i-1][j-1]+p4)/(1-p1);
        else f=(p3*dp[i-1][j-1])/(1-p1);
        km+=f*c[i-j];
      }
      dp[i][i]=km/(1-c[i]);
      for(int j=1;j<i;++j)
      if(j==1)dp[i][j]=(p2*dp[i][i]+p4)/(1.0-p1);
      else if(1<j&&j<=k)dp[i][j]=(p2*dp[i][j-1]+p3*dp[i-1][j-1]+p4)/(1.0-p1);
      else dp[i][j]=(p2*dp[i][j-1]+p3*dp[i-1][j-1])/(1.0-p1);
    }
    printf("%.5f\n",dp[n][m]);
  }
}

  

posted @ 2016-06-07 00:28  kiuhghcsc  阅读(113)  评论(0编辑  收藏  举报