hdu4089 概率dp

n个人排队,T在第m个位置,对于队列第一个人有以下四种情况:

1、激活失败,留在队列中等待下一次激活(概率为p1)

2、失去连接,出队列,然后排在队列的最后(概率为p2)

3、激活成功,离开队列(概率为p3)

4、服务器瘫痪,服务器停止激活,所有人都无法激活了

求服务器瘫痪时T在队列中的位置<=k的概率

dp[i][j]表示i个人排队,T站在j位置时的:最终瘫痪符合条件的概率

转移方程比较好想,程序里面也有

1 //j=1 dp[i][j]=p1*dp[i][j]+p2*dp[i][i]+p4;
2 //j=[2,k] dp[i][j]=p1*dp[i][j]+p2*dp[i][j-1]+p3*dp[i-1][j-1]+p4;
3 //j=[k+1,i] dp[i][j]=p1*dp[i][j]+p2*dp[i][j-1]+p3*dp[i-1][j-1];

关键在第一个方程用到了最后一个变量,表面上形成了环,实际上设最后一个为x,循环迭代代代代就解出dp[i][i]然后再回来接触dp[i][1-j]==

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<math.h>
 4 #include<algorithm>
 5 using namespace std;
 6 #define eps 1e-8
 7 //j=1 dp[i][j]=p1*dp[i][j]+p2*dp[i][i]+p4;
 8 //j=[2,k] dp[i][j]=p1*dp[i][j]+p2*dp[i][j-1]+p3*dp[i-1][j-1]+p4;
 9 //j=[k+1,i] dp[i][j]=p1*dp[i][j]+p2*dp[i][j-1]+p3*dp[i-1][j-1];
10 double dp[2005][2005],p[2005],p_jie[2005],c[2005];
11 int main()
12 {
13   int n,m,k,i,j;
14   double tp,p[5],tmp;
15   while (~scanf("%d%d%d",&n,&m,&k))
16   {
17     for (i=1;i<=4;i++) scanf("%lf",&p[i]);
18     
19     if (p[4]<eps) {
20       printf("0.00000\n");
21       continue;
22     }
23     
24     tp=p[2]/(1-p[1]);
25     p_jie[0]=1.0;
26     for (i=1;i<=n;i++) p_jie[i]=p_jie[i-1]*tp;
27     
28     dp[1][1]=p[4]/(1-p[1]-p[2]);
29     for (i=2;i<=n;i++)
30     {
31       c[1]=p[4]/(1-p[1]);
32       for (j=2;j<=i;j++)
33         if (j<=k) c[j]=(p[3]*dp[i-1][j-1]+p[4])/(1-p[1]);
34         else c[j]=(p[3]*dp[i-1][j-1])/(1-p[1]);
35     
36       tmp=0;
37       for (j=1;j<=i;j++)
38         tmp+=p_jie[i-j]*c[j];
39       dp[i][i]=tmp/(1-p_jie[i]);
40     
41       dp[i][1]=tp*dp[i][i]+p[4]/(1-p[1]);
42       for (j=2;j<i;j++)
43         if (j<=k) dp[i][j]=tp*dp[i][j-1]+
44           dp[i-1][j-1]*p[3]/(1-p[1])+p[4]/(1-p[1]);
45         else dp[i][j]=tp*dp[i][j-1]+dp[i-1][j-1]*p[3]/(1-p[1]);
46     }
47     printf("%.5lf\n",dp[n][m]);
48   }
49   return 0;
50 }
View Code

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4089

 

posted on 2015-03-07 16:16  xiao_xin  阅读(127)  评论(0编辑  收藏  举报

导航