HDU3853 LOOPS dp C语言

题目:http://acm.hdu.edu.cn/showproblem.php?pid=3853

题目大意:二维地图,分成r*c的方格,从左上角走到右下角,在每个格内有一定的概率停在原地,右移一格,下移一格,三种情况概率和为1。每次移动(包括停在原地)耗费两点魔法值。求从起点到终点所耗魔法值的期望。

算法:dp

思路:期望公式 E = x1 * p1 + x2 * p2 + …… +xn * pn

   假设每格内停在原地概率为map[i][j].x,右移一格概率为map[i][j].y,下移一格概率为map[i][j].z;exp[i][j] 为从起点走到ij格所耗魔法值的期望。

   同时可以得知exp[r][c] = 0。

   于是状态转移方程 exp[i][j] = (2 + exp[i][j]) * map[i][j].x + (2 + exp[i][j + 1]) * map[i][j].y + (2 + exp[i + 1][j]) * map[i][j].z

   将等式右边的exp[i][j]移到左边,可以得出exp[i][j]的表达式

    exp[i][j] = (2 * map[i][j].x + (2 + exp[i][j + 1]) * map[i][j].y + (2 + exp[i + 1][j]) * map[i][j].z) / (1 - map[i][j].x)

   这里有个坑~~观察到分母(1 - map[i][j].x)可能为0,于是需要判断一下  if(1 - map[i][j].x < EPS) exp[i][j] = 0; (EPS = 1e-8)

   将最下面一行和最右边一列处理一下~就可以从exp[r][c]和顺的dp回来~exp[1][1]就是答案

提交情况:WA n次,AC 1次

总结:要注意坑啊……细节……

AC code:

View Code
 1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4
5 #define MAXN (1000 + 100)
6 #define EPS 1e-8
7 #define INF 0xfffffff
8
9 struct MAP {
10 double x;
11 double y;
12 double z;
13 }map[MAXN][MAXN];
14 double exp[MAXN][MAXN];
15
16 void Clear() {
17 memset(map, 0, sizeof(map));
18 memset(exp, INF, sizeof(exp));
19 }
20
21 void Insert(int r, int c) {
22 double x, y, z;
23 int i, j;
24 for(i = 1; i <= r; ++i) {
25 for(j = 1; j <= c; ++j) {
26 scanf("%lf%lf%lf", &x, &y, &z);
27 map[i][j].x = x;
28 map[i][j].y = y;
29 map[i][j].z = z;
30 }
31 }
32 }
33
34 double DP(int r, int c) {
35 int i, j;
36 exp[r][c] = 0;
37 for(i = c - 1; i > 0; --i) {
38 if(1 - map[r][i].x < EPS)
39 exp[r][i] = 0;
40 else
41 exp[r][i] = (2 * map[r][i].x + (2 + exp[r][i + 1]) * map[r][i].y) / (1. - map[r][i].x);
42 }
43 for(j = r - 1; j > 0; --j) {
44 if(1 - map[j][c].x < EPS)
45 exp[j][c] = 0;
46 else
47 exp[j][c] = (2 * map[j][c].x + (2 + exp[j + 1][c]) * map[j][c].z) / (1. - map[j][c].x);
48 }
49 for(j = c - 1; j > 0; --j)
50 for(i = r - 1; i > 0; --i) {
51 if(1 - map[i][j].x < EPS)
52 exp[i][j] = 0;
53 else
54 exp[i][j] = (2 * map[i][j].x + (2 + exp[i][j + 1]) * map[i][j].y +
55 (2 + exp[i + 1][j]) * map[i][j].z) / (1 - map[i][j].x);
56 }
57 return exp[1][1];
58 }
59
60 int main() {
61 int r, c;
62 while(~scanf("%d%d",&r, &c)) {
63 Clear();
64 Insert(r, c);
65 printf("%.3lf\n", DP(r, c));
66 }
67 return 0;
68 }
posted @ 2011-07-20 15:58  cloehui  阅读(243)  评论(0编辑  收藏  举报