【HDU3853】LOOPS
题意
有一个R*C的方格。一个人想从(1,1)走到(r,c)。在每个格子都有三种选择,向下,向右,或者原地不动。每个格子里的每个选择都有一定的概率。而每次移动都需要消耗2点的能量,问期望消耗的能量是多少。
分析
概率DP入门题。
f[i][j]为从(i,j)到(r,c)的期望消耗。从(i,j)有三种转移方法,在原地不动,向右,向下。在原地不动的概率是G[i][j][1],向右的概率为G[i][j][2],向下的概率为G[i][j][3]。但是在原地不动是不消耗能量的。(想一想如果在原地不动也消耗能量的话应该怎么解决)所以转移我们只考虑转移到右边和下边的情况。
f[i][j]=(f[i+1][j]*G[i][j][2]+f[i][j+1]*G[i][j][3]+2)/(1-G[i][j][1]).
code
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <cstdio> 2 #include <algorithm> 3 #include <cstring> 4 #include <iostream> 5 #include <cmath> 6 7 using namespace std; 8 const int maxn=1000+100; 9 const int eps=1e-5; 10 11 double G[maxn][maxn][5]; 12 double f[maxn][maxn]; 13 14 int r,c; 15 int main(){ 16 while(scanf("%d%d",&r,&c)!=EOF&&r&&c){ 17 for(int i=1;i<=r;i++){ 18 for(int j=1;j<=c;j++){ 19 for(int l=1;l<=3;l++){ 20 scanf("%lf",&G[i][j][l]); 21 } 22 } 23 } 24 memset(f,0,sizeof(f)); 25 for(int i=r;i>=1;i--){ 26 for(int j=c;j>=1;j--){ 27 if(i==r&&j==c) 28 continue; 29 if(fabs(1-G[i][j][1])<=eps)continue; 30 f[i][j]=(f[i][j+1]*G[i][j][2]+f[i+1][j]*G[i][j][3]+2)/(1-G[i][j][1]); 31 } 32 } 33 34 printf("%.3f\n",f[1][1]); 35 } 36 return 0; 37 }