您的位置:首页 > 运维架构

hdu 3853 LOOPS 动态规划

2015-02-17 11:16 651 查看
题目链接: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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: