HDU-3853 LOOPS(概率DP求期望)
题目大意:在nxm的方格中,从(1,1)走到(n,m)。每次只能在原地不动、向右走一格、向下走一格,概率分别为p1(i,j),p2(i,j),p3(i,j)。求行走次数的期望。
题目分析:状态转移方程很容易得到:
E(i,j)=p1(i,j)*E(i,j)+p2(i,j)*E(i,j+1)+p3(i,j)*E(i+1,j)。
代码如下:
# include<iostream> # include<cstdio> # include<cmath> # include<cstring> # include<algorithm> using namespace std; const double eps=1e-8; int n,m; double p1[1005][1005]; double p2[1005][1005]; double p3[1005][1005]; double dp[1005][1005]; int main() { while(~scanf("%d%d",&n,&m)) { for(int i=0;i<n;++i) for(int j=0;j<m;++j) scanf("%lf%lf%lf",&p1[i][j],&p2[i][j],&p3[i][j]); dp[n-1][m-1]=0; for(int i=n-2;i>=0;--i){ if(fabs(1-p1[i][m-1])<eps) continue; dp[i][m-1]=(p3[i][m-1]*(dp[i+1][m-1]+2)+2*p1[i][m-1])/(1-p1[i][m-1]); } for(int i=m-2;i>=0;--i){ if(fabs(1-p1[n-1][i])<eps) continue; dp[n-1][i]=(p2[n-1][i]*(dp[n-1][i+1]+2)+2*p1[n-1][i])/(1-p1[n-1][i]); } for(int i=n-2;i>=0;--i) for(int j=m-2;j>=0;--j){ if(fabs(1-p1[i][j])<eps) continue; dp[i][j]=(p2[i][j]*(dp[i][j+1]+2)+p3[i][j]*(dp[i+1][j]+2)+2*p1[i][j])/(1-p1[i][j]); } printf("%.3lf\n",dp[0][0]); } return 0; }