状态转移方程: 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]);
}
}
浙公网安备 33010602011771号