hdu4405_概率dp

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4405

题目大意就是某个人玩大富翁(飞行棋)有一个骰子,有6个面标有1,2,3,4,5,6并且每一次 过得每一个数的概率一样。他在N+1的 格子上玩(最开始位于0处), 当他走到N处或者超出N的时候就完了, 在这之间还有一些格子是有特权的当你走上这些格子可以 跳到相应的前面去(这一题只能往前跳)比如你走到2,当2可以直接跳到4时候你就到了4,那么问你投色子的次数的期望为多少??

期望一般是从 前往后 推(这里的后是指格子上的数字,比如 先退出N,再推出N-1)根据博客里面讲的就是每一次的前面一个就是紧邻他后面6个 格子的期望值的和(因为色子最多是6)就是dp[i]=1.0/6(dp[i+k]的和)+1(1<=k<=6)

然后如果你走到可以跳到前面去的那么这里的期望就和你跳的地方一样。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 #include <cstdlib>
 6 #include <cmath>
 7 #include <set>
 8 #include <map>
 9 #include <queue>
10 #include <vector>
11 #define INF 0x3f3f3f3f
12 using namespace std;
13 
14 double dp[100010];
15 int jump[100010];
16 int main()
17 {
18     int n, m, x, y;
19     while(~scanf("%d %d", &n, &m) && n + m)
20     {
21         memset(jump, -1, sizeof(jump));
22         memset(dp, 0, sizeof(dp));
23         for(int i = 0; i < m; i++)
24         {
25             scanf("%d %d", &x, &y);
26             jump[x] = y;
27         }
28         for(int i = n - 1; i >= 0; i--)
29         {
30             if(jump[i] != -1)
31                 dp[i] = dp[jump[i]];
32             else
33             {
34                 for(int j = 1; j <= 6; j++)
35                 {
36                     if(i + j <= n)
37                         dp[i] += dp[i + j] * 1.0 / 6;
38                 }
39                 dp[i]++;
40             }
41         }
42         printf("%.4lf\n", dp[0]);
43     }
44     return 0;
45 }

 

posted @ 2016-07-21 21:08  海无泪  阅读(98)  评论(0编辑  收藏  举报