状态转移方程: dp[i][j]=map[i][j].r * (dp[i][j+1]+2) + map[i][j].d * (dp[i+1][j]+2) + map[i][j].s * (dp[i][j]+2) (dp[i][j]用来记录期望)
于是乎,等式两边都有 dp[i][j],此时应当进行移项!
得到新的转移方程:dp[i][j]=[map[i][j].r * (dp[i][j+1]+2) + map[i][j].d * (dp[i+1][j]+2) + map[i][j].s*2]/(1-map[i][j].s)
由此方程我们可知, 如果分母 map[i][j].s=1 ,dp[i][j]的值为无穷大,此时不满足题意(本题的坑),所以此情况应特殊处理。
注意处理边界,搞起吧。。。
#include <stdio.h> #define MAXN 1010 #define inf 1000000000 double dp[MAXN][MAXN]; struct Tpoint { double s; //self double r; //right double d; //down }map[MAXN][MAXN]; int r,c; int main(){ while (scanf("%d%d",&r,&c)!=EOF) { for (int i=0; i<r; i++) { for (int j=0; j<c; j++) { scanf("%lf%lf%lf",&map[i][j].s,&map[i][j].r,&map[i][j].d); } } dp[r-1][c-1]=0; for(int i=r-2; i>=0;i--) { int j=c-1; if(map[i][j].s==1) {dp[i][j]=0; continue;} //can not get off the grid dp[i][j]=map[i][j].d * (dp[i+1][j]+2) + map[i][j].s*2; dp[i][j]/=(1-map[i][j].s); } for(int j=c-2; j>=0;j--) { int i=r-1; if(map[i][j].s==1) {dp[i][j]=0; continue;} //can not get off the grid dp[i][j]=map[i][j].r * (dp[i][j+1]+2) + map[i][j].s*2; dp[i][j]/=(1-map[i][j].s); } for (int i=r-2; i>=0; i--) { for (int j=c-2; j>=0; j--) { if(map[i][j].s==1) {dp[i][j]=0; continue;} //can not get off the grid dp[i][j]=map[i][j].r * (dp[i][j+1]+2) + map[i][j].d * (dp[i+1][j]+2) + map[i][j].s*2; dp[i][j]/=(1-map[i][j].s); } } printf("%.3f\n",dp[0][0]); } }