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

Leohh發表於2017-09-21

題目連結: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 }

 

相關文章