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