类型:概率DP
题意:一条直线下飞行棋,色子六个面等概率。同时存在一些飞机航线,到了某个点可以直接飞到后面的另一个点,可以连飞,保证一个点至多一条航线。求到达或者超过终点 所需要 掷色子的期望次数。
思路:
如果可以飞,那么从这个点到终点的期望次数 等于 飞到的那个点 到终点的期望次数。 否则,就是掷一次色子,然后后面六个点到终点的期望次数 求平均 +1;
换种表示:
if (canFly) dp[now] = dp[flyTo];
else dp[now] = (dp[now+1]+dp[now+2]+...+dp[now+6]) / 6;
代码:
#include <cstdio> #include <cstring> #define N 100010 #define M 1010 double dp[N]; int airLine[N]; int main() { int n, m; while (scanf("%d%d", &n, &m) != EOF) { if (n == 0 && m == 0) break; memset(airLine, -1, sizeof(airLine)); for (int i = 0; i < m; i++) { int u, v; scanf("%d%d", &u, &v); airLine[u] = v; } for (int i = n; i < n+10; i++) dp[i] = 0; for (int i = n-1; i >= 0; i--) { if (airLine[i] != -1) { dp[i] = dp[airLine[i]]; continue; } dp[i] = 1; for (int j = 1; j <= 6; j++) { dp[i] += (1.0/6.0)*dp[i+j]; } } printf("%.4lf ", dp[0]); } return 0; }