1. 程式人生 > >lightoj 1030 - Discovering Gold(概率DP)

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;
}