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

Output for Sample Input

3

 

1

101

 

2

10 3

 

3

3 6 9

Case 1: 101.0000000000

Case 2: 13.000

Case 3: 15


分析:這道題是求期望的,有兩種解法,第一是直接求期望,求期望從後往前推,第二是求概率,進一步求期望,求概率從前往後推。

方法1:(以下內容爲轉載,原帖鏈接:@see_you_later

//格子和值都是一樣,所以下述的話,值就是格子,格子就是值。。。
比如這樣的9個格子,我們總底往上來
對於第9個格子,因爲只有9,能取的期望就是9;
對於第8個格子,8是一定要取的,而9也是一定回取的,所以對於第8個格子,期望就是17;
對於第7個格子,7是一定要取的,對於後面可能是直接取了9,或者先取8再取9,情況是滿足,對於每種情況概率是1/2,所以就是7+9/2+(8+9)/2=20;
PS:
上面的情況,在7後面的時候,我們可能取9,或者先取8,那麼其實就是拿了第8個格子的期望和第9個格子期望,期望就是能取的值,然後*概率,全部情況的總和就是新的期望,有人會奇怪那7呢?我們的前提是對於第7格一定拿7啊;
對於第6個格子,那麼就是6一定要拿的,然後會拿7,拿8,拿9,他們的期望*概率的總和+他能取的值就是6的第6個格子的期望;
...以此類推;
對於概率的其實一想更簡單...
我們一開始就在1,概率就是1,然後扔一個骰子對於每個面的概率就是1/6,那麼dp[i]代表概率,每次對能到達的地方更新概率,最後期望就是值乘以概率的總和+1,1是一定要取的哦~
附上自己的代碼:

#include<cstdio>
#define min(a,b) (a<b?a:b)
const int MAXN=100+5;
double EX[MAXN];
int a[MAXN];
//EX[i]表示從i格子開始,能獲得的gold的期望
int main(){
    int T;scanf("%d",&T);
    int CASE=0;
    while(T--){
        int N;scanf("%d",&N);
        for(int i=1;i<=N;++i)
            scanf("%d",a+i);
        for(int i=N;i>=1;i--){
            EX[i]=a[i];double temp=0.0;
            for(int j=i+1;j<=min(i+6,N);++j){
                temp+=EX[j];
            }
            if(i!=N)EX[i]+=temp/min(N-i,6);
        }
        printf("Case %d: ",++CASE);
        printf("%.8lf\n",EX[1]);
    }
}

方法2:(感覺自己還沒理解,方法上面也提到了,但感覺自己還沒理解,先留下flag吧)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章