hdu 3853 概率dp
题意:在一个R*C的迷宫里,一个人在最左上角,出口在右下角,在每个格子上,该人有几率向下,向右或者不动,求到出口的期望
现在对概率dp有了更清楚的认识了
设dp[i][j]表示(i,j)到(R,C)需要消耗的能量
则:
dp[i][j]=p1[i][j]*dp[i][j]+p2[i][j]*dp[i][j+1]+p3[i][j]*dp[i+1][j]+2;
化简得到:
dp[i][j]=p2[i][j]*dp[i][j+1]/(1-p1[i][j])+p3[i][j]*dp[i+1][j]/(1-p1[i][j])+2/(1-p1[i][j]);
注意一种情况就是p1[i][j]==1的情况。
题目只是保证答案小于1000000.但是有的点可能永远都不可能到达的。
所以这样的点出现p1[i][j]是允许的。
否则就会WA了。
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #include<cmath> 6 #include<queue> 7 #include<map> 8 using namespace std; 9 #define MOD 1000000007 10 const int INF=0x3f3f3f3f; 11 const double eps=1e-5; 12 typedef long long ll; 13 #define cl(a) memset(a,0,sizeof(a)) 14 #define ts printf("*****\n"); 15 const int MAXN=1005; 16 int n,m,tt; 17 double p1[MAXN][MAXN],p2[MAXN][MAXN],p3[MAXN][MAXN],dp[MAXN][MAXN]; 18 int main() 19 { 20 int i,j,k; 21 #ifndef ONLINE_JUDGE 22 freopen("1.in","r",stdin); 23 #endif 24 while(scanf("%d%d",&n,&m)!=EOF) 25 { 26 for(i=0;i<n;i++) 27 { 28 for(j=0;j<m;j++) 29 { 30 scanf("%lf%lf%lf",&p1[i][j],&p2[i][j],&p3[i][j]); 31 } 32 } 33 cl(dp); 34 for(i=n-1;i>=0;i--) 35 { 36 for(j=m-1;j>=0;j--) 37 { 38 if(i==n-1&&j==m-1) continue; 39 if(fabs(p1[i][j]-1)<eps) 40 { 41 dp[i][j]=0; 42 continue; 43 } 44 dp[i][j]=p2[i][j]*dp[i][j+1]/(1-p1[i][j])+p3[i][j]*dp[i+1][j]/(1-p1[i][j])+2/(1-p1[i][j]); 45 } 46 } 47 printf("%.3f\n",dp[0][0]); 48 } 49 }