题意:飞行棋...从0开始摇六面色子,摇到几就走几步,走到 N 及以上就完成游戏 , 且给定 M 个点对( xi , yi ),若走到 xi 便会直接跳到 yi ,求完成游戏需要摇色子次数的期望
分析:设 dp[ i ] 表示从 i 开始走完成游戏的期望,则容易推出转移方程 dp[ i ] = 1 + 1/6 * ;
如果遇到M个点对之一,则 dp[ xi ] = dp[ yi ] ,因为走到 xi 会直接跳到 yi (无缝衔接) ,所以两点的期望值等同。
代码:
#include<vector>
#include<cstdio>
#include<iostream>
using namespace std;
const int N = 1E5+5;
double dp[N];
vector<int> G[N];
int main()
{
int n,m,u,v;
while(cin>>n>>m)
{
if(n==0&&m==0) break;
for(int i=0;i<=n;i++)
G[i].clear();
for(int i=0;i<m;i++)
{
cin>>u>>v;
G[u].push_back(v);
}
for(int i=0;i<=6;i++) dp[i+n]=0; //走到n及以上的期望为零
for(int i=n-1;i>=0;i--)
{
if(G[i].size())
dp[i]=dp[G[i][0]];
else
{
dp[i]=1;
for(int k=1;k<=6;k++)
dp[i]+=dp[i+k]/6;
}
}
printf("%.4f\n",dp[0]);
}
return 0;
}