当前位置:首页 > 牛客题解 > 动态规划实战:牛客51817题地下城游戏的最优解法详解

动态规划实战:牛客51817题地下城游戏的最优解法详解

3天前牛客题解61

截图未命名.jpg 动态规划实战:牛客51817题地下城游戏的最优解法详解 动态规划 逆向思维 路径规划 牛客网 第1张

一、问题分析与解法思路

地下城游戏问题是一个典型的动态规划应用场景。我们需要逆向思考,从终点反推每个位置所需的最小初始生命值。这种方法可以避免正向思考时复杂的生命值跟踪问题。

二、完整代码实现(带详细注释)

#include <iostream>
#include <vector>
#include <algorithm>
using namespACe std;

int calculateMinimumHP(vector<vector<int>>& dungeon) {
    int n = dungeon.size();
    if (n == 0) return 1;  // 空地直接返回最小生命值1
    int m = dungeon[0].size();
    
    // dp[i][j]表示从(i,j)到终点所需的最小初始血量
    vector<vector<int>> dp(n, vector<int>(m, 0));
    
    // 初始化终点位置
    dp[n-1][m-1] = max(1, 1 - dungeon[n-1][m-1]);
    
    // 初始化最后一行(只能向右移动)
    for (int j = m-2; j >= 0; --j) {
        dp[n-1][j] = max(1, dp[n-1][j+1] - dungeon[n-1][j]);
    }
    
    // 初始化最后一列(只能向下移动)
    for (int i = n-2; i >= 0; --i) {
        dp[i][m-1] = max(1, dp[i+1][m-1] - dungeon[i][m-1]);
    }
    
    // 动态规划填充其他位置(可以向右或向下移动)
    for (int i = n-2; i >= 0; --i) {
        for (int j = m-2; j >= 0; --j) {
            int min_required = min(dp[i+1][j], dp[i][j+1]);  // 选择需求较小的路径
            dp[i][j] = max(1, min_required - dungeon[i][j]);  // 确保生命值至少为1
        }
    }
    
    return dp[0][0];  // 返回起点所需最小生命值
}

int main() {
    ios::sync_with_stdio(false);  // 禁用C与C++的输入输出同步
    cin.tie(nullptr);            // 解除cin与cout的绑定
    
    int n, m;  // 地图的行数和列数
    cin >> n >> m;
    vector<vector<int>> dungeon(n, vector<int>(m));  // 地下城地图
    
    // 读取地图数据
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            cin >> dungeon[i][j];
        }
    }
    
    cout << calculateMinimumHP(dungeon) << endl;
    return 0;
}

三、算法核心解析

  1. 逆向动态规划:从终点向起点计算,避免了正向计算的复杂性

  2. 状态定义:dp[i][j]表示从(i,j)到终点所需的最小初始生命值

  3. 边界处理

    • 终点初始化:确保终点处生命值至少为1

    • 最后一行和最后一列:只能单向移动的特殊情况

  4. 状态转移方程

    • dp[i][j] = max(1, min(dp[i+1][j], dp[i][j+1]) - dungeon[i][j])

    • 选择需求较小的路径,并确保生命值不低于1

四、复杂度分析

五、优化思考

  1. 空间优化:可将空间复杂度优化到O(min(n,m)),只存储当前行或列

  2. 预处理优化:某些特殊情况可以提前处理

  3. 并行计算:大规模地图可考虑并行计算不同区域


原创内容 转载请注明出处

分享给朋友:

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。