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

题目链接: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
",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 }
原文地址:https://www.cnblogs.com/Leohh/p/7572009.html