首页 > 代码库 > hdu 3853 概率DP 简单

hdu 3853 概率DP 简单

http://acm.hdu.edu.cn/showproblem.php?pid=3853

题意:有R*C个格子,一个家伙要从(0,0)走到(R-1,C-1) 每次只有三次方向,分别是不动,向下,向右,告诉你这三个方向的概率,以及每走一步需要耗费两个能量,问你走到终点所需要耗费能量的数学期望:

回头再推次,思想跟以前的做过的类似

注意点:分母为0的处理

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <iostream>
#include <iomanip>
#include <cmath>
#include <map>
#include <set>
#include <queue>
using namespace std;

#define ls(rt) rt*2
#define rs(rt) rt*2+1
#define ll long long
#define ull unsigned long long
#define rep(i,s,e) for(int i=s;i<e;i++)
#define repe(i,s,e) for(int i=s;i<=e;i++)
#define CL(a,b) memset(a,b,sizeof(a))
#define IN(s) freopen(s,"r",stdin)
#define OUT(s) freopen(s,"w",stdout)
const ll ll_INF = ((ull)(-1))>>1;
const double EPS=1e-8;
const int MAXN = 1000+100;

double dp[MAXN][MAXN],mat[MAXN][MAXN][3];
int r,c;

int main()
{
    while(~scanf("%d%d",&r,&c))
    {
        CL(dp,0);
        for(int i=1;i<=r;i++)
            for(int j=1;j<=c;j++)
                for(int k=0;k<3;k++)
                    scanf("%lf",&mat[i][j][k]);
        for(int i=r;i>0;i--)
            for(int j=c;j>0;j--)
            {
                if(i==r && j==c)dp[i][j]=0;
                if(abs(mat[i][j][0]-1.0)<EPS)continue;
                dp[i][j]=(dp[i+1][j]*mat[i][j][2]+dp[i][j+1]*mat[i][j][1]+2)/(1.0-mat[i][j][0]);
            }
        printf("%.3lf\n",dp[1][1]);
    }
    return 0;
}