题目分析
普通的概率dp,很明显
for(int k = 1; k <= 6; k++)
dp[i] = 1.0*dp[i+k]/6.0;
但是这道题因为有飞行棋的飞行线,我们可以用一个fa数组存一下,写状态转移方程时一旦其有父亲节点,那么该点的期望等于父亲节点的期望。
#include <cstdio>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 100005;
int fa[maxn];
double dp[maxn];
int main()
{
int n,m;
while(scanf("%d %d", &n, &m) != EOF){
if(!n && !m) break;
memset(dp, 0, sizeof(dp));
memset(fa, -1, sizeof(fa));
while(m--)
{
int from,to;
scanf("%d %d", &from, &to);
fa[from] = to;
}
for(int i = n-1; i >= 0; i--)
{
if(fa[i] != -1) dp[i] = dp[fa[i]];
else
{
for(int j = 1; j <= 6; j++)
dp[i] += 1.0*dp[i+j]/6.0;
dp[i] += 1.0;
}
}
printf("%.4lf\n", dp[0]);
}
return 0;
}