HDU 3853 LOOPS (二维坐标Dp)
状态转移方程: 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]);
		
	}
}
posted on 2011-07-20 09:19  Eucalyptus  阅读(546)  评论(0编辑  收藏  举报