HDU 3853 概率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) 这个点到出口 (R,C) 花费的魔法值的期望。

    那么,我们有:

        f[i][j] = 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] = p_left[i][j](f[i][j+1] + p_down[i][j]*f[i+1][j]

const  int maxn = 1008 ;
double  dp[maxn][maxn]  ;
double  p[maxn][maxn][4]  ;
const double eps = 1e-7 ;

int  main(){
     int i , j , n  , m , u , v ;
     while(cin>>n>>m){
         for(i = 1 ; i <= n ; i++){
             for(j = 1 ; j <= m ; j++){
                  scanf("%lf%lf%lf" ,&p[i][j][1] ,&p[i][j][2] ,&p[i][j][3]) ;
             }
         }
         memset(dp , 0 , sizeof(dp)) ;
         for(i = n ; i >= 1 ; i--){
             for(j = m ; j >= 1 ; j--){
                  if(i == n && j == m) continue ;
                  if(fabs(1.0 - p[i][j][1]) <  eps) continue ;
                  dp[i][j] = (2.0 + p[i][j][2] * dp[i][j+1]+ p[i][j][3] * dp[i+1][j])
                             / (1.0 - p[i][j][1]) ;
             }
         }
         printf("%.3lf\n" , dp[1][1]) ;
     }
     return 0 ;
}




你可能感兴趣的:(HDU 3853 概率dp)