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
",dp[1][1]);
    }
}
View Code
原文地址:https://www.cnblogs.com/lienus/p/4263234.html