lightoj 1030 - Discovering Gold(概率DP)

You are in a cave, a long cave! The cave can be represented by a 1 x N grid. Each cell of the cave can contain any amount of gold.

Initially you are in position 1. Now each turn you throw a perfect 6 sided dice. If you get X in the dice after throwing, you add X to your position and collect all the gold from the new position. If your new position is outside the cave, then you keep throwing again until you get a suitable result. When you reach the Nth position you stop your journey. Now you are given the information about the cave, you have to find out the expected number of gold you can collect using the given procedure.

Input

Input starts with an integer T (≤ 100), denoting the number of test cases.

Each case contains a blank line and an integer N (1 ≤ N ≤ 100) denoting the dimension of the cave. The next line contains N space separated integers. The ith integer of this line denotes the amount of gold you will get if you come to the ith cell. You may safely assume that all the given integers will be non-negative and no integer will be greater than 1000.

Output

For each case, print the case number and the expected number of gold you will collect. Errors less than 10-6 will be ignored.

Sample Input

3

1

101

2

10 3

3

3 6 9

Sample Output

Case 1: 101.0000000000

Case 2: 13.000

Case 3: 15

PS:题意:现在有n个山洞,编号为1-n,每个洞里都有一定数量的黄金,现在有一枚骰子,上面有1-6的数字,比如现在位置是i,掷骰子的数目为x,则可以到达洞穴i+x,如果i+x超过了n,则重新掷。现在问在洞穴n拿到黄金的期望。

我们现在的位置在1号位,设期望为E(1)。因为我们要求从1到n的期望,所以我们遍历的时候应该从后往前遍历,这样才能保证我们的起始位置是1。因为骰子有六面,所以我们可以得到公式,E(i)=(E(i+1)+E(i+2)+E(i+3)+E(i+4)+E(i+5)+E(i+6))/6+gold[i]。因为我们要保证起点是从1开始所以我们要从后往前遍历。

我们已样例三为例,3,6,9.

E(3)=9。因为在三号位不可能掷骰子掷出负数到2号位或1号位。

E(2)=6+E(3)/1=15。因为现在在2号位只能掷到三号位。

E(1)=(E(2)+E(3))/2+gold[1]=15。其实也可以解释,现在在一号位,剩下2号位和3号位的概率各占一半。

#include <iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<map>
#include<queue>
#include<set>
#include<cmath>
#include<stack>
#include<string>
const int maxn=1e3+10;
const int mod=10007;
const int inf=1e8;
#define me(a,b) memset(a,b,sizeof(a))
#define lowbit(x) x&(-x)
typedef long long ll;
using namespace std;
double dp[maxn];
int main()
{
    int t,Case=1;
    scanf("%d",&t);
    while(t--)
    {
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            scanf("%lf",&dp[i]);
        for(int i=n-1;i>=1;i--)
        {
            int temp=min(6,n-i);//骰子最大数为6
            for(int j=1;j<=temp;j++)//从后往前遍历
                dp[i]+=(double)dp[i+j]/temp;
        }
        printf("Case %d: %.7f\n",Case++,dp[1]);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41292370/article/details/85983061