题目: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;
}