版权声明:转载请注明出处 https://blog.csdn.net/FSAHFGSADHSAKNDAS/article/details/81749020
链接
http://acm.hdu.edu.cn/showproblem.php?pid=4405
题解
这是一道概率DP入门题
如果正着
,遇到的问题就是一个点的前驱可能多余或者少于
,因此我必须建一个
然后统计入度,以确定我转移的时候除以多少
但是倒着推,我就可以放心地除以
了,只是我在面临那些能飞的点时需要处理一下
表示从
走到终点的期望步数,那么
,其中
表示从
点能飞到的最后一个点
代码
//概率DP
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <cctype>
#define maxn 101000
#define cl(x,y) memset(x,y,sizeof(x))
#define eps 1e-8
using namespace std;
int last[maxn], N, M;
double f[maxn];
int dfs(int pos)
{
if(!last[pos] or last[pos]==pos)return last[pos]=pos;
return last[pos]=dfs(last[pos]);
}
int read(int x=0)
{
int c, f=1;
for(c=getchar();!isdigit(c);c=getchar())if(c=='-')f=-1;
for(;isdigit(c);c=getchar())x=(x<<1)+(x<<3)+c-48;
return f*x;
}
int init()
{
int i, a, b;
cl(last,0), cl(f,0);
N=read(), M=read();
if(!N and !M)return 0;
for(i=1;i<=M;i++)a=read(), b=read(), last[a]=b;
for(i=1;i<=N;i++)dfs(i);
return 1;
}
void dp()
{
int i, j;
double ans=0;
for(i=N-1;i>=0;i--)
if(i==last[i])
{
f[i]=1;
for(j=1;j<=6 and i+j<=N;j++)f[i]+=f[last[i+j]]/6.0;
}
printf("%.4lf\n",f[0]);
}
int main()
{
while(init())dp();
return 0;
}