题意:在一个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("*****
");
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
",dp[0][0]);
48 }
49 }