首页 > 代码库 > hdu 4405 概率dp 2012年金华亚洲网络赛--虽然水,但是是自己独立做的第一道概率dp

hdu 4405 概率dp 2012年金华亚洲网络赛--虽然水,但是是自己独立做的第一道概率dp

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


e[i]:当前在位置i还需要走的步数期望

受刘汝佳的AC自动机那个后缀链接写法的启发,我的x[i]通过逆序算出来连续有“flight line ”的时候,能到达的最远距离,

        rep(i,0,m)
        {
            scanf("%d%d",&xx,&yy);
            x[xx]=yy;
        }
        for(int i=n;i>=0;i--)
            if(x[i]!=-1 && x[x[i]] != -1)
                x[i]=x[x[i]];
写的时候犯了一个二逼错误导致我以为自己方程推错了,,,见注释

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

#define rep(i,s,e) for(int i=s;i<e;i++)
#define repe(i,s,e) for(int i=s;i<=e;i++)
#define reped(i,s,e) for(int i=s;i>=e;i--)
#define arclr(aa,v) memset(aa,v,sizeof(aa))
const double p=1.0/6;

const int MAXN = 100000+30;

double e[MAXN],p2;
int x[MAXN];

int main()
{
    //freopen("hdu4405.txt","r",stdin);
    int xx,yy,n,m;
    while(~scanf("%d%d",&n,&m) && n+m)
    {
        //p2=m*1.0/n;
        arclr(x,0xff);
        rep(i,0,m)
        {
            scanf("%d%d",&xx,&yy);
            x[xx]=yy;
        }
        for(int i=n;i>=0;i--)
            if(x[i]!=-1 && x[x[i]] != -1)
                x[i]=x[x[i]];
        arclr(e,0);
        reped(i,n-1,0)
        {
            if(x[i]==-1)
            {
                reped(j,6,1)
                    e[i]+=e[i+j];
                e[i]=e[i]/6.0+1;
                continue;
            }
            if(x[i]!=-1 && x[x[i]] != -1)
            {
                e[x[i]]=e[x[x[i]]];
                x[i]=x[x[i]];//写成x[i]=x[i+x[i]],二逼了
            }
            e[i]=e[x[i]];
        }
        printf("%.4lf\n",e[0]);
    }
    return 0;
}