hdu 3853 写傻了的期望dp,不能正推?!!

//下面是错误代码...

 1 #include "iostream"
 2 #include "cstdio"
 3 #include "cstring"
 4 #include "algorithm"
 5 #include "cmath"
 6 using namespace std;
 7 const double eps = 1e-5;
 8 double dp[1010][1010];
 9 int R, C;
10 double p[1010][1010][3];
11 bool cant[1010][1010];
12 
13 int main()
14 {
15     int i, j, k;
16     while(scanf("%d%d", &R, &C)!=EOF) {
17         memset(dp, 0, sizeof(dp));
18         memset(cant, 0, sizeof(cant));
19         for(i = 1; i <= R; ++i) {
20             for(j = 1; j <= C; ++j) {
21                 scanf("%lf%lf%lf", &p[i][j][0], &p[i][j][1], &p[i][j][2]);
22                 if(fabs(p[i][j][0] - 1.0) > eps) {
23                     dp[i][j] = (dp[i][j - 1] + 2) * p[i][j - 1][1] + (dp[i - 1][j] + 2) * p[i - 1][j][2] + 2 * p[i][j][0];
24                     dp[i][j] /= (1 - p[i][j][0]);
25                     if(j==1)
26                         cant[i][j - 1] = 1;
27                     if(i==1)
28                         cant[i - 1][j] = 1;
29 
30                     if(cant[i][j - 1] && cant[i - 1][j] && (i != 1 || j != 1))
31                         cant[i][j] = 1, dp[i][j] = 0;
32                 }
33                 else
34                     cant[i][j] = 1, dp[i][j] = 0;
35                 //printf("%d %d dp[%d][%d] == %f\n",cant[i][j - 1], cant[i - 1][j], i, j, dp[i][j]);
36             }
37         }
38         dp[R][C] = 0;
39         if(!cant[R][C - 1])
40             dp[R][C] += (dp[R][C - 1] + 2) * p[R][C - 1][1];
41         if(!cant[R - 1][C])
42             dp[R][C] += (dp[R - 1][C] + 2) * p[R - 1][C][2];
43         printf("%.3f\n", dp[R][C]);
44     }
45 }

 

//对拍之后发现,上面的程序和标程的输出差的好远好远,所以一定是计算公式错了...

//生成随机数据的程序

 1 #include "iostream"
 2 #include "cstdio"
 3 #include "cstring"
 4 #include "algorithm"
 5 #include "ctime"
 6 using namespace std;
 7 void Print()
 8 {
 9     int tot = 100, i;
10     for(i = 1; i <= 2; i++) {
11         if(tot == 0) {
12             printf("0 ");
13             continue;
14         }
15         int tmp = rand() % (tot + 1);
16         printf("%f ", (double)tmp / 100.0);
17         tot -= tmp;
18     }
19     printf("%f\n", (double)tot / 100.0);
20 }
21 
22 int main()
23 {
24     srand(time(NULL));
25     freopen("input.txt", "w", stdout);
26     int i, j, r, c;
27     r = 10,c = 21;
28     printf("%d %d\n", r, c);
29     for(i = 1; i <= r; ++i) {
30         for(j = 1; j <= c; ++j) {
31             Print();
32         }
33     }
34 }

 

//期望 = 概率 * 取值,所以这题的状态转移方程其实在一开始就确定了...,自己相当然的去设计转移方程就会陷入误区

//正确的代码

 1 #include "iostream"
 2 #include "cstdio"
 3 #include "cstring"
 4 #include "algorithm"
 5 #include "cmath"
 6 using namespace std;
 7 const double eps = 1e-5;
 8 int r, c;
 9 double dp[1010][1010], p[1010][1010][3];
10 
11 int main()
12 {
13     int i, j, k;
14     while(scanf("%d%d", &r, &c) != EOF) {
15         for(i = 1; i <= r; ++i)
16             for(j = 1; j <= c; ++j)
17                 for(k = 0; k <= 2; ++k)
18                     scanf("%lf", &p[i][j][k]);
19         memset(dp, 0, sizeof(dp));
20         for(i = r; i >= 1; --i) {
21             for(j = c; j >= 1; --j) {
22                 if(i == r && j == c)
23                     continue;
24                 if(fabs(p[i][j][0] - 1) < eps)
25                     continue;
26                 dp[i][j] = (dp[i][j + 1] + 2) * p[i][j][1] + (dp[i + 1][j] + 2) * p[i][j][2] + 2 * p[i][j][0];
27                 dp[i][j] /= (1 - p[i][j][0]);
28             }
29         }
30         printf("%.3f\n", dp[1][1]);
31     }
32 }

 

//记忆化搜索

 1 #include "iostream"
 2 #include "cstdio"
 3 #include "cstring"
 4 #include "algorithm"
 5 #include "cmath"
 6 using namespace std;
 7 const double eps = 1e-5;
 8 int r, c;
 9 double dp[1010][1010], p[1010][1010][3];
10 bool vis[1010][1010];
11 double dfs(int row, int col)
12 {
13     if(vis[row][col])
14         return dp[row][col];
15     vis[row][col] = 1;
16     if(row <= 0 || row > r || col <= 0 || col > c || fabs(p[row][col][0] - 1) < eps)
17         return dp[row][col] = 0;
18     else {
19         dp[row][col] = p[row][col][1] * (dfs(row, col + 1) + 2) + p[row][col][2] * (dfs(row + 1, col) + 2) + p[row][col][0] * 2;
20         dp[row][col] /= 1 - p[row][col][0];
21     }
22     return dp[row][col];
23 }
24 
25 int main()
26 {
27     int i, j, k;
28     while(scanf("%d%d", &r, &c) != EOF) {
29         for(i = 1; i <= r; ++i)
30             for(j = 1; j <= c; ++j)
31                 for(k = 0; k <= 2; ++k)
32                     scanf("%lf", &p[i][j][k]);
33         memset(dp, 0, sizeof(dp));
34         memset(vis, 0, sizeof(vis));
35         printf("%.3f\n", dfs(1, 1));
36     }
37 }

 

posted @ 2015-02-13 23:05  AC_Phoenix  阅读(151)  评论(0编辑  收藏  举报