概率dp

此题的巧妙之处在于倒推,如果正推状态转移无法正确进行。令f[i]表示从i到游戏结束所需要的期望步数,则(1)f[i] = f[j],强制转移(2)f[i] = (f[j] + 1) / 6,共6种合法情况。则答案变成f[0]的值。代码如下:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cmath>
 5 #include <algorithm>
 6 #include <map>
 7 #include <stack>
 8 #include <string>
 9 #include <ctime>
10 #include <queue>
11 #define mem0(a) memset(a, 0, sizeof(a))
12 #define mem(a, b) memset(a, b, sizeof(a))
13 #define lson l, m, rt << 1
14 #define rson m + 1, r, rt << 1 | 1
15 #define eps 0.0000001
16 #define lowbit(x) ((x) & -(x))
17 #define memc(a, b) memcpy(a, b, sizeof(b))
18 #define xx(a) ((a) * (a))
19 using namespace std;
20 #define LL __int64
21 #define DB double
22 #define pi 3.14159265359
23 #define MD 10000007
24 #define INF (int)1e9
25 double f[110000];
26 int last[110000];
27 int main()
28 {
29         //freopen("input.txt", "r", stdin);
30         int n, m;
31         while(cin>> n>> m, n || m) {
32                 mem0(last);
33                 for(int i = 1; i <= m; i++) {
34                         int u, v;
35                         cin>> u>> v;
36                         last[u] = v;
37                 }
38                 mem0(f);
39                 for(int i = n - 1; i >= 0; i--) {
40                         if(last[i]) {
41                                 f[i] = f[last[i]];
42                                 continue;
43                         }
44                         for(int j = 1; j <= 6; j++) f[i] += (f[i + j] + 1) / 6;
45                 }
46                 printf("%.4f\n", f[0]);
47         }
48         return 0;
49 }
View Code

 

posted @ 2014-10-15 20:35  jklongint  阅读(134)  评论(0编辑  收藏  举报