HDU-3853 LOOPS(概率DP求期望)

题目大意:在nxm的方格中,从(1,1)走到(n,m)。每次只能在原地不动、向右走一格、向下走一格,概率分别为p1(i,j),p2(i,j),p3(i,j)。求行走次数的期望。

题目分析:状态转移方程很容易得到:

E(i,j)=p1(i,j)*E(i,j)+p2(i,j)*E(i,j+1)+p3(i,j)*E(i+1,j)。

 

代码如下:

# include<iostream>
# include<cstdio>
# include<cmath>
# include<cstring>
# include<algorithm>
using namespace std;

const double eps=1e-8;

int n,m;
double p1[1005][1005];
double p2[1005][1005];
double p3[1005][1005];
double dp[1005][1005];

int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        for(int i=0;i<n;++i)
            for(int j=0;j<m;++j)
                scanf("%lf%lf%lf",&p1[i][j],&p2[i][j],&p3[i][j]);
        dp[n-1][m-1]=0;
        for(int i=n-2;i>=0;--i){
            if(fabs(1-p1[i][m-1])<eps) continue;
            dp[i][m-1]=(p3[i][m-1]*(dp[i+1][m-1]+2)+2*p1[i][m-1])/(1-p1[i][m-1]);
        }
        for(int i=m-2;i>=0;--i){
            if(fabs(1-p1[n-1][i])<eps) continue;
            dp[n-1][i]=(p2[n-1][i]*(dp[n-1][i+1]+2)+2*p1[n-1][i])/(1-p1[n-1][i]);
        }
        for(int i=n-2;i>=0;--i)
            for(int j=m-2;j>=0;--j){
                if(fabs(1-p1[i][j])<eps) continue;
                dp[i][j]=(p2[i][j]*(dp[i][j+1]+2)+p3[i][j]*(dp[i+1][j]+2)+2*p1[i][j])/(1-p1[i][j]);
            }
        printf("%.3lf\n",dp[0][0]);
    }
    return 0;
}

  

posted @ 2016-03-27 21:26  20143605  阅读(198)  评论(0编辑  收藏  举报