2 0 8 3 2 4 4 5 7 8 0 0
1.1667 2.3441
/*题意:有一个飞行棋n个格子,刚開始在0这个位置,每次能够扔色子,扔到x则能够移动x格
假设到达的位置>=n则胜利
另外在棋盘上还有m对点x,y表示在位置x能够直接飞行到y
求到达胜利平均的扔色子次数
分析:求期望,假设dp[i]表示在点i位置到达胜利所须要的平均次数,则我们须要求dp[0]
dp[n],dp[n+1]....等是知道的:为0
而对于dp[i]能够到达:
假设点i不能飞行:dp[i+1],dp[i+2],dp[i+3],dp[i+4],dp[i+5],dp[i+6]且等概率:1/6
假设i点位置能够飞行则能够到达飞行的点
由E(aA+bB+cC+dD...)=aEA+bEB+....
可知:dp[i]=1/6*dp[i+1]+1/6*dp[i+2]...
*/
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <queue>
#include <algorithm>
#include <map>
#include <cmath>
#include <iomanip>
#define INF 99999999
typedef long long LL;
using namespace std;
const int MAX=100000+10;
int n,m,size;
int head[MAX];
double dp[MAX];//dp[i]表示从i到达目标所须要的平均次数(期望)
struct Node{
int y,next;
Node(){}
Node(int Y,int NEXT):y(Y),next(NEXT){}
}node[MAX];
void Init(){
memset(head,-1,sizeof head);
memset(dp,0,sizeof dp);
size=0;
}
void InsertNode(int x,int y){
node[size]=Node(y,head[x]);
head[x]=size++;
}
double Solve(int x){
double sum=0,num=0;
for(int i=head[x];i != -1;i=node[i].next){
sum+=dp[node[i].y];
++num;
}
return sum/num;
}
int main(){
int x,y;
while(~scanf("%d%d",&n,&m),n+m){
Init();
for(int i=0;i<m;++i){
scanf("%d%d",&x,&y);
InsertNode(x,y);
}
for(int i=n-1;i>=0;--i){
if(head[i] != -1){
dp[i]=Solve(i);
}else{
dp[i]=(dp[i+1]+dp[i+2]+dp[i+3]+dp[i+4]+dp[i+5]+dp[i+6])/6+1;
}
}
printf("%.4lf\n",dp[0]);
}
return 0;
}原文:http://www.cnblogs.com/mengfanrong/p/3857274.html