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