• 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 }
  • 相关阅读:
    『中级篇』docker导学(一)
    计算机或许已经烂大街了,女生学计算机没出路吗?
    「初级篇」跟我一起学docker(17)--多节点mesos集群
    「初级篇」跟我一起学docker(18)--持续集成(初级终结篇)
    「初级篇」跟我一起学docker(16)--单节点mesos集群
    QT socket 多线程管理
    mysql数据库引擎 MyISAM和 InnoDB区别
    sql 删除表格delete drop truncate 区别(转)
    按层次遍历二叉树
    php基础排序算法 冒泡排序 选择排序 插入排序 归并排序 快速排序
  • 原文地址:https://www.cnblogs.com/Leohh/p/7572009.html
Copyright © 2020-2023  润新知