hdu 4089 概率dp

 1 /*
 2 题目大意:注册一款游戏需要排队,一共有四种事件:
 3 1.注册失败,队列不变,概率为p1
 4 2.注册过程中断开连接,正在注册的人排到队列的末尾,概率为p2
 5 3.注册成功,移出队列,概率为p3
 6 4.服务器暂停服务,概率为p4
 7 求一个人他前面有不超过k-1个人的时候暂停服务的概率。
 8 从前往后推,统计答案太麻烦,所以选择从后往前推。
 9 dp(i,j)表示一共i个人,他排在j位置的达到目标状态的概率。
10 j==1   dp[i][j]=dp[i][j]*p1+dp[i][i]*p2+p4;
11 1<j<=k dp[i][j]=dp[i][j]*p1+dp[i][j-1]*p2+dp[i-1][j-1]*p3+p4;
12 j> k   dp[i][j]=dp[i][j]*p1+dp[i][j-1]*p2+dp[i-1][j-1]*p3;
13 {i>=j}
14 化简:
15 j==1   dp[i][j]=dp[i][i]*p21+p41;
16 1<j<=k dp[i][j]=dp[i][j-1]*p21+dp[i-1][j-1]*p31+p41;
17 j> k   dp[i][j]=dp[i][j-1]*p21+dp[i-1][j-1]*p31;
18 p=1-p1;
19 p21=p2/p;
20 p31=p3/p;
21 p41=p4/p;
22 dp[1][1]=dp[1][1]*p21+p41,得dp[1][1]=p41/(1-p21);
23 
24 j=1 dp[i][1]=dp[i][i]*p21+p41;
25 j=2 dp[i][2]=dp[i][1]*p21+dp[i-1][1]*p31+p41;
26 .................................................................................
27 j==k dp[i][k]=dp[i][k-1]*p21+dp[i-1][k-1]*p31;
28 j==k+1 dp[i][j]=dp[i][k]*p21+dp[i-1][k]*p31;
29 .................................................................................
30 j==i dp[i][i]=dp[i][i-1]*p21+dp[i-1][i-1]*p31;
31 可发现后面一部分都是常数项(递推过来已求出的),设后面一部分为c[j]
32 可以消元求解
33 ai=(((.....(((ai*p+c1)*p+c2)*p+c5)*p+c6*)............+ci)
34 ai=ai*p^i+c1*p^(i-1)+c2*p^(i-2)+.......+ci*p^0
35 可求出ai。
36 */
37 #include <iostream>
38 #include <cstdio>
39 #include <cstring>
40 #include <cmath>
41 using namespace std;
42 
43 const double eps=1e-8;
44 const int maxn=2005;
45 double dp[maxn][maxn];
46 double c[maxn];
47 double pp[maxn]={1.0};
48 
49 int main()
50 {
51     int n,m,k,i,j;
52     double p0,p1,p2,p3,p4,p5,p6,p7;
53     while(~scanf("%d%d%d",&n,&m,&k))
54     {
55         scanf("%lf%lf%lf%lf",&p1,&p2,&p3,&p4);
56         if(fabs(p4)<eps){puts("0.00000");continue;}
57         p0=1-p1;p5=p2/p0;p6=p3/p0;p7=p4/p0;
58         for(i=1;i<=n;i++) pp[i]=pp[i-1]*p5;
59         dp[1][1]=p7/(1-p5);
60         c[1]=p7;
61         for(i=2;i<=n;i++)
62         {
63             for(j=2;j<=i;j++)
64             {
65                 c[j]=dp[i-1][j-1]*p6;
66                 if(j<=k) c[j]+=p7;
67             }
68             double temp=0.0;
69             for(j=1;j<=i;j++) temp+=c[j]*pp[i-j];
70             dp[i][i]=temp/(1-pp[i]);
71             dp[i][1]=p5*dp[i][i]+c[1];
72             for(j=2;j<i;j++)
73                 dp[i][j]=p5*dp[i][j-1]+c[j];
74         }
75         printf("%.5lf
",dp[n][m]);
76     }
77     return 0;
78 }
原文地址:https://www.cnblogs.com/xiong-/p/4136430.html