首页 > 代码库 > HDU 4405 Aeroplane chess

HDU 4405 Aeroplane chess

期望,$dp$。

设$dp[i]$表示当前在位置$i$,到达目标位置所需的期望步数。

因为有直接跳跃的方案,所以要先预处理好每一个位置最后跳在哪个位置,设位置$i$最终跳到了位置$t[i]$。

那么,$dp[i]=sum(1/6*dp[t[i+j]])+1$。

#pragma comment(linker, "/STACK:1024000000,1024000000")#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#include<vector>#include<map>#include<set>#include<queue>#include<stack>#include<iostream>using namespace std;typedef long long LL;const double pi=acos(-1.0),eps=1e-6;void File(){    freopen("D:\\in.txt","r",stdin);    freopen("D:\\out.txt","w",stdout);}template <class T>inline void read(T &x){    char c = getchar();    x = 0;    while(!isdigit(c)) c = getchar();    while(isdigit(c))    {        x = x * 10 + c - 0;        c = getchar();    }}int n,m;int t[100010];bool f[100010];vector<int>tree[100010];double dp[100010];void dfs(int x,int y){    t[y]=max(t[y],x);    for(int i=0;i<tree[y].size();i++)        dfs(x,tree[y][i]);}int main(){    while(~scanf("%d%d",&n,&m))    {        if(n==0&&m==0) break;        memset(f,0,sizeof f);        for(int i=0;i<=n;i++) tree[i].clear();        for(int i=0;i<m;i++)        {            int a,b; scanf("%d%d",&a,&b);            tree[b].push_back(a); f[a]=1;        }        for(int i=1;i<=n;i++) t[i]=i;        for(int i=0;i<=n;i++)        {            if(f[i]) continue;            dfs(i,i);        }        memset(dp,0,sizeof dp);        for(int i=n-1;i>=0;i--)        {            for(int j=1;j<=6;j++)            {                if(i+j>=n) continue;                dp[i]=dp[i]+1.0/6*dp[t[i+j]];            }            dp[i]=dp[i]+1;        }        printf("%.4f\n",dp[0]);    }    return 0;}

 

HDU 4405 Aeroplane chess