码迷,mamicode.com
首页 > 其他好文 > 详细

hdu 3853 LOOPS 动态规划

时间:2015-02-17 11:37:59      阅读:179      评论:0      收藏:0      [点我收藏+]

标签:

题目链接: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;
}

 

hdu 3853 LOOPS 动态规划

标签:

原文地址:http://www.cnblogs.com/dishu/p/4294979.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!