HDU-4405 Aeroplane chess(概率DP求期望)

题目大意:一个跳棋游戏,每置一次骰子前进相应的步数。但是有的点可以不用置骰子直接前进,求置骰子次数的平均值。

题目分析:状态很容易定义:dp(i)表示在第 i 个点出发需要置骰子的次数平均值。则状态转移方程为:

dp(i)=singma(pk*dp(i+k))+1  (如果在 i 处必须置骰子才能前进)

dp(i)=dp(s)    (如果在 i 处能直接到达s处)

代码如下:

# include<iostream>
# include<cstdio>
# include<vector>
# include<cstring>
# include<algorithm>
using namespace std;

int n,m;
bool flag[100010];
double dp[100010];
vector<int>g[100010];

void init()
{
    memset(dp,0,sizeof(dp));
    memset(flag,false,sizeof(flag));
    for(int i=0;i<=n;++i)
        g[i].clear();
    int x,y;
    while(m--)
    {
        scanf("%d%d",&x,&y);
        g[y].push_back(x);
    }
}

double solve()
{
    for(int i=0;i<g[n].size();++i){
        int v=g[n][i];
        flag[v]=true;
    }
    for(int i=n-1;i>=0;--i){
        if(!flag[i]){
            dp[i]=1.0;
            for(int j=1;j<=6;++j)
                dp[i]+=dp[i+j]/6.0;
            flag[i]=true;
        }
        for(int j=0;j<g[i].size();++j){
            int v=g[i][j];
            dp[v]=dp[i];
            flag[v]=true;
        }
    }
    return dp[0];
}

int main()
{
    while(scanf("%d%d",&n,&m)&&(n+m))
    {
        init();
        printf("%.4lf
",solve());
    }
    return 0;
}

  

原文地址:https://www.cnblogs.com/20143605--pcx/p/5322473.html