LightOJ 1030 【概率DP求期望】

题意:
n个格子,每个格子有一个值。从1开始,每次扔6个面的骰子,扔出几点就往前几步,然后把那个格子的金子拿走;
如果扔出的骰子+所在位置>n,就重新扔,直到在n;
问取走这些值的期望值是多少;
思路:
【1】 【2】 【3】【4】 【5】 【6】 【7】 【8】 【9】
//格子和值都是一样,所以下述的话,值就是格子,格子就是值。。。
比如这样的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是一定要取的哦~
下面贴出直接求期望的code
#include<bits/stdc++.h>
using namespace std;
typedef __int64 LL;
const int N=1e2+10;
double dp[N];
double ans;

int main()
{
    int T,cas=1;
    scanf("%d",&T);
    while(T--)
    {
        int n,k;
        double temp;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            scanf("%lf",&dp[i]);
        for(int i=n-1;i>=1;i--)
        {
            temp=0;
            k=min(6,n-i);
            for(int j=i+1;j<i+1+k;j++)
                temp+=dp[j];
            dp[i]=dp[i]+temp/(double)k;
        }
        printf("Case %d: %.10lf\n",cas++,dp[1]);
    }
    return 0;
}


posted @ 2016-10-31 16:34  see_you_later  阅读(564)  评论(0编辑  收藏  举报