Discovering Gold (概率dp(基础))

来源:互联网 发布:体育场馆播放软件 编辑:程序博客网 时间:2024/05/29 01:52

【题目来源】:https://vjudge.net/problem/LightOJ-1030
【题意】
有一个1*n的图形,每一个方格编号从1~n,有各自的金钱的数量,起点为1,给出一个六面的骰子,摇动骰子得到点数x,向右移动x步,得到相应的金钱,若是移动x步超过了n,则需要重新摇动,直到不大于n为止。
问:从方格1开始摇动骰子,到达方格n的金钱的期望是多少。
【思路】
推荐一篇博客:http://www.cnblogs.com/keyboarder-zsq/p/6216762.html
概率dp,,,额,第一次做。。。
假设处在方格i上,那么i+1,i+2,i+3,i+4,i+5,i+6(前提是i+6<=n)的概率均是1/6,
那么假设共有9个格子,从后往前推,在第九个格子时,假设金钱是v9,那么第九个格子的期望是1*v9(因为是终点),那么第八个格子必须要到第九个格子,那么期望是v8+v9,再看第七个格子,有两种情况:第一种直接到第九个格子,第二种先到第八个格子,再到第九个格子,两种发生的概率均是1/2,那么期望是v7+v9/+(v8+v9)/2,依次类推。
我们一开始就在1,概率就是1,然后扔一个骰子对于每个面的概率就是1/6,那么dp[i]代表概率,每次对能到达的地方更新概率,最后期望就是值乘以概率的总和+1。
【代码】

#include<bits/stdc++.h>using namespace std;double dp[110];int main(){    int T,t=1;    cin>>T;    while(T--)    {        int n;        cin>>n;        for(int i=1;i<=n;i++)        {            cin>>dp[i];        }        for(int i=n-1;i>=1;i--)        {            int x=min(6,n-i);            double res=0;            for(int j=i+1;j<i+x+1;j++)            {               res+=dp[j];            }            dp[i]+=res/(double)x;        }        printf("Case %d: %lf\n",t++,dp[1]);    }}