lightoj1030_期望

题目链接:http://lightoj.com/volume_showproblem.php?problem=1030

题目大意:在一个1*N的格子里,每个格子都有相应的金币数,走到相应格子的话,就会得到该格子的金币。 
现在有一个人在1这个位置,手里有一颗色子,色子摇到几,他就前进几步,但有一种情况例外,如果当前位置+色子数 > N,那么他就会重新摇色子。 
走到N这个位置的话,意味着游戏结束了。 
问游戏结束时,这个人得到金币的期望。

解题思路:这题要倒着推,由N推向1 
设dp[k]为到达k这个位置时得到金币的期望,m为该点和N这个位置的距离,gold[k]为k这个位置的金币数,因为走的位置不能超过N,所以要取min(m,6) 
那么dp[k] = 1 / min(m,6) * (dp[k + 1] + dp[k+2] + … + dp[min(m,6)]) + gold[k]

 1 #include <algorithm>
 2 #include <iostream>
 3 #include <cstring>
 4 #include <cstdlib>
 5 #include <cstdio>
 6 #include <vector>
 7 #include <ctime>
 8 #include <queue>
 9 #include <list>
10 #include <set>
11 #include <map>
12 using namespace std;
13 #define INF 0x3f3f3f3f
14 typedef long long LL;
15 
16 double a[105], dp[105];
17 int main()
18 {
19     int t, n;
20     scanf("%d", &t);
21     for(int ca = 1; ca <= t; ca++)
22     {
23         scanf("%d", &n);
24         for(int i = 1; i <= n; i++)
25         {
26             scanf("%lf", &a[i]);
27         }
28         memset(dp, 0, sizeof(dp));
29         dp[n] = a[n];
30         for(int i = n-1; i > 0; i--)
31         {
32             dp[i] = a[i];
33             int m = min(6, n - i);
34             for(int j = 1; j <= m; j++)
35                 dp[i] += dp[i + j] / m;
36         }
37         printf("Case %d: %.6f
", ca, dp[1]);
38     }
39     return 0;
40 }
原文地址:https://www.cnblogs.com/luomi/p/5929494.html