1. 程式人生 > >HDU 3853 LOOPS:期望dp【網格型】

HDU 3853 LOOPS:期望dp【網格型】

clu pre 答案 blog printf iostream memset 題意 一個

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

題意:

  有一個n*m的網格。

  給出在每個格子時:留在原地、向右走一格,向下走一格的概率。

  每走一格會消耗2點體力。

  問你從(1,1)到達終點(n,m)消耗體力的期望。

題解:

  表示狀態:

    dp[i][j] = rest steps(剩余路程花費體力的期望)

    i,j:現在的位置

  找出答案:

    ans = dp[0][0]

  如何轉移:

    期望dp的套路:考慮子期望。。。

    now: dp[i][j]

    能轉移到的子期望:dp[i][j](留在原地),dp[i][j+1](向右),dp[i+1][j](向下)

    dp[i][j] = dp[i][j]*trans[i][j][0]

          + ( dp[i][j+1]*trans[i][j][1]

            + dp[i+1][j]*trans[i][j][2] + 2 )

    移項:

    dp[i][j] = ( dp[i][j+1]*trans[i][j][1]

            + dp[i+1][j]*trans[i][j][2] + 2 )

          / (1-trans[i][j][0])

  邊界條件:

    dp[n-1][m-1] = 0

    到達終點後不用再耗體力。

  註:(1)對於所有越界的概率應看成0。

    (2)除法要保證除數不為0。

AC Code:

 1 // state expression:
 2 // dp[i][j] = rest steps
 3 // i,j: present pos
 4 //
 5 // find the answer:
 6 // ans = dp[0][0]
 7 //
 8 // transferring:
 9 // now: dp[i][j] -> dp[i][j], dp[i+1][j], dp[i][j+1]
10 // dp[i][j] = dp[i][j]*trans[i][j][0]
11 //            + (dp[i][j+1]*trans[i][j][1]
12 // + dp[i+1][j]*trans[i][j][2] + 2) 13 // dp[i][j] = (dp[i][j+1]*trans[i][j][1] 14 // + dp[i+1][j]*trans[i][j][2] + 2) 15 // / (1-trans[i][j][0]) 16 // 17 // boundary: 18 // dp[n-1][m-1] = 0 19 #include <iostream> 20 #include <stdio.h> 21 #include <string.h> 22 #define MAX_N 1005 23 24 using namespace std; 25 26 int n,m; 27 double dp[MAX_N][MAX_N]; 28 double trans[MAX_N][MAX_N][3]; 29 30 void read() 31 { 32 for(int i=0;i<n;i++) 33 { 34 for(int j=0;j<m;j++) 35 { 36 for(int k=0;k<3;k++) 37 { 38 scanf("%lf",&trans[i][j][k]); 39 } 40 } 41 } 42 } 43 44 void solve() 45 { 46 memset(dp,0,sizeof(dp)); 47 for(int i=n-1;i>=0;i--) 48 { 49 for(int j=m-1;j>=0;j--) 50 { 51 if(i==n-1 && j==m-1) continue; 52 if(trans[i][j][0]==1.0) continue; 53 dp[i][j]=(dp[i][j+1]*trans[i][j][1]+dp[i+1][j]*trans[i][j][2]+2.0)/(1.0-trans[i][j][0]); 54 } 55 } 56 } 57 58 void print() 59 { 60 printf("%.3f\n",dp[0][0]); 61 } 62 63 int main() 64 { 65 while(scanf("%d%d",&n,&m)!=EOF) 66 { 67 read(); 68 solve(); 69 print(); 70 } 71 }

HDU 3853 LOOPS:期望dp【網格型】