概率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

 

你可能感兴趣的:(dp)