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 }
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4089