zoukankan      html  css  js  c++  java
  • HDU-4089 Activation (概率DP求概率)

    题目大意:一款新游戏注册账号时,有n个用户在排队。每处理一个用户的信息时,可能会出现下面四种情况:

    1.处理失败,重新处理,处理信息仍然在队头,发生的概率为p1;

    2.处理错误,处理信息到队尾重新排队,发生的概率为p2;

    3.处理成功,队头信息处理成功,出队,发生的概率为p3;

    4.服务器故障,队伍中所有信息丢失,发生的概率为p4;

    小明现在在队伍中的第m个位置,问当他前面的信息条数不超过k-1时服务器故障的概率。

    题目分析:这道题的状态转移方程不难写。定义状态dp(i,j)表示在有 i 个人的队伍中,他排在第 j 个位置时到达要求状态的概率。则状态转移方程为:

    dp(i,1)=p1*dp(i,1)+p2*dp(i,i)+p4

    dp(i,j)=p1*dp(i,j)+p2*(i,j-1)+p3*dp(i-1,j-1)+p4  (2<=j<=k)

    dp(i,j)=p1*dp(i,j)+p2*(i,j-1)+p3*dp(i-1,j-1)  (k<j<=i)

    整理一下,并另p21=p2/(1-p1),p31=p3/(1-p1),p41=p4/(1-p1),则得到:

    dp(i,1)=p21*dp(i,i)+p41

    dp(i,j)=p21*dp(i,j-1)+p31*dp(i-1,j-1)+p41  (2<=j<=k)

    dp(i,j)=p21*dp(i,j-1)+p31*dp(i-1,j-1)  (k<j<=i)

    这样就可以通过递推求解。

    为了书写方便,把上面的三个转移方程用两个方程表示出来:

    dp(i,1)=p21*dp(i,i)+c(1)

    dp(i,j)=p21*dp(i,j-1)+c(j)  (2<=j<=i)

    dp(i,i)可以通过迭代得到:

    (1-p21^i)dp(i,i)=∑(p21^(i-j))*c(j)  (1<=j<=i)

    ps:得加特判,否则会WA!!。。。

    代码如下:

    # include<iostream>
    # include<cstdio>
    # include<cmath>
    # include<cstring>
    # include<algorithm>
    using namespace std;
    
    const double eps=1e-5;
    
    int n,m,k;
    double p1,p2,p3,p4;
    double dp[2005][2005];
    
    int main()
    {
        while(~scanf("%d%d%d",&n,&m,&k))
        {
            scanf("%lf%lf%lf%lf",&p1,&p2,&p3,&p4);
            if(p4<eps){
                printf("0.00000
    ");
                continue;
            }
            double p21=p2/(1-p1);
            double p31=p3/(1-p1);
            double p41=p4/(1-p1);
            dp[1][1]=p41/(1-p21);
            for(int i=2;i<=n;++i){
                dp[i][i]=0;
                for(int j=1;j<=i;++j){
                    if(j==1) dp[i][i]+=pow(p21,i-j)*p41;
                    else if(j>=2&&j<=k) dp[i][i]+=pow(p21,i-j)*(p31*(dp[i-1][j-1])+p41);
                    else dp[i][i]+=pow(p21,i-j)*p31*dp[i-1][j-1];
                }
                dp[i][i]/=(1-pow(p21,i));
                for(int j=1;j<i;++j){
                    if(j==1) dp[i][j]=p21*dp[i][i]+p41;
                    else if(j>=2&&j<=k) dp[i][j]=p21*dp[i][j-1]+p31*dp[i-1][j-1]+p41;
                    else dp[i][j]=p21*dp[i][j-1]+p31*dp[i-1][j-1];
                }
            }
            printf("%.5lf
    ",dp[n][m]);
        }
        return 0;
    }
    

      

  • 相关阅读:
    Linux新手随手笔记2.4-使用DHCP动态管理主机地址
    在word中输入任意角度旋转图片
    VBA注释临时
    VBA改写VBA代码
    【转载】robocopy的用法
    Excel数组排序+图片统一大小
    一键调节音量
    合并文档时让第一页为奇数
    智能跳转---TC资源管理器
    win7一键拖动生成快速启动栏
  • 原文地址:https://www.cnblogs.com/20143605--pcx/p/5324032.html
Copyright © 2011-2022 走看看