HDU4405(概率DP求期望)

题目:http://acm.hdu.edu.cn/showproblem.php?pid=4405

 

题意:飞行棋,从0到n,置骰子,置到几就往前走几步,前进中会有捷径,比如2和5连到一起了,那你走到2时可以直接跳到

5,如果5和8连到一起了,那你还可以继续跳到8,最后问跳到n时平均置几次骰子。也就是求期望。

 

全期望公式:http://zh.wikipedia.org/wiki/%E5%85%A8%E6%9C%9F%E6%9C%9B%E5%85%AC%E5%BC%8F

全概率公式:http://zh.wikipedia.org/wiki/%E5%85%A8%E6%A6%82%E7%8E%87%E5%85%AC%E5%BC%8F

概率期望学习:http://kicd.blog.163.com/blog/static/126961911200910168335852/

 

#include <iostream>
#include <string.h>
#include <stdio.h>

using namespace std;
const int N=100005;

struct node
{
    int y,next;
};

bool vis[N];
node path[N];
int first[N],t;
double dp[N];

void add(int x,int y)
{
    path[t].y=y;
    path[t].next=first[x];
    first[x]=t++;
}

int main()
{
    double s;
    int n,m,v;
    while(cin>>n>>m)
    {
        if(m==0&&n==0) break;
        memset(dp,0,sizeof(dp));
        memset(vis,0,sizeof(vis));
        memset(first,0,sizeof(first));
        int x,y;
        t=1;
        while(m--)
        {
            cin>>x>>y;
            add(y,x);
        }
        dp[n]=-1;
        for(int i=n; i>=0; i--)
        {
            if(!vis[i])
            {
                vis[i]=true;
                s=0;
                for(int k=1; k<=6; k++)
                    s+=dp[i+k];
                s/=6;
                dp[i]+=(s+1);
            }
            for(int k=first[i]; k; k=path[k].next)
            {
                v=path[k].y;
                dp[v]=dp[i];
                vis[v]=true;
            }
        }
        printf("%.4lf\n",dp[0]);
    }
    return 0;
}


 

你可能感兴趣的:(HDU4405(概率DP求期望))