首页 > 代码库 > lightoj1030_期望

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 0x3f3f3f3f14 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\n", ca, dp[1]);38     }39     return 0;40 }

 

lightoj1030_期望