zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    稀疏自编码器和矢量化编程
    使用支持向量机训练mnist数据
    采用libsvm进行mnist训练
    支持向量机
    月下“毛景树”
    最小费用最大流模板
    最大流模板
    选学霸
    线段树 2
    线段树 1
  • 原文地址:https://www.cnblogs.com/xiong-/p/4136430.html
Copyright © 2011-2022 走看看