题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3853
迷宫类的动态规划
首先要作个数学推导
假设留在原地、右移、下移的概率分别是a, b, c
用dp[i][j]表示在第i行第j格能走出去的期望步数
则有:
dp[i][j] = a * (dp[i][j] + 1) + b * (dp[i][j+1] + 1) + c * (dp[i+1][j] + 1)
整理一下可得:
dp[i][j] = 1/(1-a) * (a + b * (dp[i][j+1] + 1) + c * (dp[i+1][j] + 1))
然后有一个神坑我至今觉得是题目有问题
题目保证答案不大于一百万 但是却有那种停留在原地的概率为1的“死房间”
按照数学期望的算法 如果在除终点外的地方出现“死房间” 那期望的步数就应该变得无限大才对
所以我就以为题目保证答案不大于一百万是在暗示不会发生这种情况【打脸TAT
然后看了题解才发现 如果遇到死房间就直接跳过 死房间的步数期望是0 这不是强行解释吗...
各位千万记得绕开这个毫无意义的坑点
#include <cstdio> #include <cstdlib> #include <ctime> #include <iostream> #include <cmath> #include <cstring> #include <algorithm> #include <stack> #include <set> #include <queue> #include <vector> using namespace std; const int maxn = 1010; const double eps = 1e-7; double dp[maxn][maxn]; double a[maxn][maxn], b[maxn][maxn], c[maxn][maxn]; int main() { //freopen("in.txt", "r", stdin); int n, m; while(scanf("%d%d", &n, &m) == 2) { memset(dp, 0, sizeof(dp)); for(int i = 1; i <= n; i++) { for(int j = 1; j <= m; j++) { scanf("%lf%lf%lf", &a[i][j], &b[i][j], &c[i][j]); } } for(int i = n; i >= 1; i--) { for(int j = m; j >= 1; j--) { if(i == n && j == m) dp[i][j] = 0; else if(fabs(a[i][j] - 1.0) < eps) continue; else dp[i][j] = (1.0 / (1 - a[i][j])) * (a[i][j] + b[i][j] * (dp[i][j+1]+1) + c[i][j] * (dp[i+1][j]+1)); } } double ans = 2.0 * dp[1][1]; printf("%.3f\n", ans); } return 0; }
时间: 2024-10-13 08:43:13