hdu3853(概率dp)

 

题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=3853

题意:有一个人被困在一个 R*C(2<=R,C<=1000) 的迷宫中,起初他在 (1,1) 这个点,迷宫的出口是 (R,C)。在迷宫的每一个格子中,他能花费 2 个魔法值开启传送通道。假设他在 (x,y) 这个格子中,开启传送通道之后,有 p_lift[i][j] 的概率被送到 (x,y+1),有 p_down[i][j] 的概率被送到 (x+1,y),有 p_loop[i][j] 的概率被送到 (x,y)。问他到出口需要花费的魔法值的期望是多少。

分析:dp[i][j]表示从(i,j)到终点(n,m)花费的魔法值的期望。

则有:dp[i][j]=(2+dp[i][j])*p[i][j][0]+(2+dp[i][j+1])*p[i][j][1]+(2+dp[i+1][j])*p[i][j][2];

移项:dp[i][j]=(dp[i][j+1]*p[i][j][1]+dp[i+1][j]*p[i][j][2]+2*((p[i][j][0]+p[i][j][1]+p[i][j][2])==1))/(1-p[i][j][0]);

#include <cstdio>

#include <cstring>

#include <string>

#include <cmath>

#include <iostream>

#include <algorithm>

#include <queue>

#include <cstdlib>

#include <stack>

#include <vector>

#include <set>

#include <map>

#define LL long long

#define mod 100000000

#define inf 0x3f3f3f3f

#define eps 1e-6

#define N 1000010

#define FILL(a,b) (memset(a,b,sizeof(a)))

#define lson l,m,rt<<1

#define rson m+1,r,rt<<1|1

using namespace std;

double dp[1010][1010];

double p[1010][1010][3];

int main()

{

    int n,m;

    while(scanf("%d%d",&n,&m)>0)

    {

        for(int i=1;i<=n;i++)

            for(int j=1;j<=m;j++)

            for(int k=0;k<=2;k++)

            scanf("%lf",&p[i][j][k]);

        for(int i=n;i>=1;i--)

            for(int j=m;j>=1;j--)

        {

            if(n==i&&j==m)

            {

                dp[i][j]=0;

                continue;

            }

            if(fabs(1-p[i][j][0])<eps)//不断在原地循环

            {

                dp[i][j]=inf;

                continue;

            }

            dp[i][j]=(2+dp[i][j+1]*p[i][j][1]+dp[i+1][j]*p[i][j][2])/(1-p[i][j][0]);



        }

        printf("%.3lf\n",dp[1][1]);

    }

}
View Code

 

你可能感兴趣的:(HDU)