hdu 3853 LOOPS(基础DP求期望)

题目大意

有一个人被困在一个 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)。问他到出口需要花费的魔法值的期望是多少。

 

做法分析

令:f[i][j] 表示从 (i,j) 这个点到下一点花费的魔法值的期望。

那么,我们有:

    f[i][j] = 2+p_loop[i][j]*f[i][j] + p_left[i][j]*f[i][j+1] + p_down[i][j]*f[i+1][j]


移项可得:

    (1-p_loop[i][j])*f[i][j] = 2+p_left[i][j](f[i][j+1] + p_down[i][j]*f[i+1][j]

 

#include<stdio.h>

#include<math.h>

#include<string.h>

double p[3][1005][1005];

double f[1005][1005];

bool vs[1005][1005];

int R,C;

double DP(int x,int y)

{

    if(x==R&&y==C)return 0;

    if(x>R||y>C)return 0;

    if(vs[x][y])return f[x][y];

    if(fabs(p[0][x][y]-1)<1e-6)

    {

        vs[x][y]=1;

        return f[x][y]=0;

    }

    vs[x][y]=1;

    return f[x][y]=(2+p[1][x][y]*DP(x,y+1)+p[2][x][y]*DP(x+1,y))/(1-p[0][x][y]);

}

int main()

{

    while(scanf("%d%d",&R,&C)!=EOF)

    {

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

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

        scanf("%lf%lf%lf",&p[0][i][j],&p[1][i][j],&p[2][i][j]);

        memset(f,0,sizeof(f));

        memset(vs,0,sizeof(vs));

        printf("%.3lf\n",DP(1,1));

    }

}

 

你可能感兴趣的:(loop)