HDOJ3853解题报告【概率DP】

题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=3853

题目概述:

  在一个r*c的网格中有一个人有概率向右走,向下走或者留在原地,走一步产生2点花费,球走到终点的期望花费。

大致思路:

  概率DP的入门题,学会了求概率要正着推,而求期望需要逆着推。

  DP方程为:dp[i][j]=p1*dp[i][j]+p2*f[i][j+1]+p3*f[i+1][j];

复杂度分析:

  根据DP方程,显然复杂度为O(r*c*T).

代码:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstdlib>
 4 #include <cmath>
 5 #include <vector>
 6 #include <ctime>
 7 #include <map>
 8 #include <queue>
 9 #include <cstring>
10 #include <algorithm>
11 using namespace std;
12 
13 #define sacnf scanf
14 #define scnaf scanf
15 #define maxn 1010
16 #define maxm 26
17 #define inf 1061109567
18 #define Eps 0.00001
19 const double PI=acos(-1.0);
20 #define mod 7
21 #define MAXNUM 10000
22 void Swap(int &a,int &b) {int t=a;a=b;b=t;}
23 double Abs(double x) {return (x<0)?-x:x;}
24 typedef long long ll;
25 typedef unsigned int uint;
26 
27 double p[3][maxn][maxn];
28 double f[maxn][maxn];
29 
30 int main()
31 {
32     //freopen("data.in","r",stdin);
33     //freopen("data.out","w",stdout);
34     //clock_t st=clock();
35     int r,c;
36     while(~scanf("%d%d",&r,&c))
37     {
38         for(int i=1;i<=r;i++)
39             for(int j=1;j<=c;j++)
40             {
41                 scanf("%lf%lf%lf",&p[0][i][j],&p[1][i][j],&p[2][i][j]);
42                 f[i][j]=0;
43             }
44         for(int i=r;i>0;i--)
45         {
46             for(int j=c;j>0;j--)
47             {
48                 if(fabs(1-p[0][i][j])<Eps) continue;
49                 f[i][j]=(p[1][i][j]*f[i][j+1]+p[2][i][j]*f[i+1][j]+2)/(1-p[0][i][j]);
50             }
51         }
52         printf("%.3lf\n",f[1][1]);
53     }
54     //clock_t ed=clock();
55     //printf("\n\nTime Used : %.5lf Ms.\n",(double)(ed-st)/CLOCKS_PER_SEC);
56     return 0;
57 }

 

posted @ 2017-03-03 17:11  CtrlKismet  阅读(160)  评论(0编辑  收藏  举报