详解LeetCode地下城游戏(动态规划)——区分两种状态表示形式

地下城游戏

题目链接: 174. 地下城游戏

状态表示:

按照以往题的表示,dp[i][j]表示:从起点(0,0)位置到达(i,j)位置时,所需的最小初始健康值。但是如果这么去表示,不仅要考虑到达(i,j)位置的最小初始健康值,由于魔法球的存在,还需要考虑到达(i,j)位置时的健康值,因为魔法球会对算后续位置的最小初始健康值产生影响

下面用题目中的示例1为例,演示:

由此可知,到达魔法球位置所需的最低初始健康值和上一次的最低初始健康值保持一致,而魔法球会增加健康值,这就会对后面的结果产生影响,因此我们不仅要考虑到达(i,j)位置的最小初始健康值,还需要考虑到达(i,j)位置时的健康值,以保证后续结果的正确性

因此,我们可以试着用dp[i][j]表示:以(i,j)位置为起点,到达终点位置时,所需的最小健康值 。当(i,j)位置是魔法球时,可以用之前的dp[i+1][j]和dp[i][j+1]中的最小健康值减去治疗量,就能得到当前的位置到达终点位置时所需的最小健康值dp[i][j](注意:dp[i][j]不能小于0,最小值为1);当(i,j)位置是恶魔时,也是这样处理,实际上就是加上了需要扣除的健康值

通过这种状态表示,我们最终能够求得结果!

总结:

  1. 这道题的难点在于怎么去处理健康值增加的问题,健康值的增加不能为之前的损失提供帮助,只会对后续有帮助
  2. 如果按照第一种状态表示,dp[i][j]仅仅只表示了从(0,0)位置到达(i,j)位置所需的最小初始健康值,而由于魔法球的存在,导致后续的健康值会增加,因此我们还需要去记录当前位置的健康值,以保证后续计算最小初始健康值的正确性
  3. 如果按照第二种状态表示,dp[i][j]表示从(0,0)位置出发,按照最优路径到达(i,j)位置时,还需要剩余的最小健康值(为了到达终点后,健康值为1)。即dp[i][j]不仅表示了从(i,j)位置到达终点位置所需的最小初始健康值,还表示了从(0,0)位置出发到达(i,j)位置时,所需剩余的最小健康值(即当前健康值)
  4. 比较两种状态表示,可知,第二种表示更合理,更方便后续的填表

状态转移方程

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

初始化

创建表时,多创建一行(第m行)和一列(第n列),除dp[m][n-1] = 1(dp[m-1][n] 也可初始化为1,表示救出公主后还需剩余1点健康值),其他都初始化为正无穷(以防对填表产生影响)

填表顺序

从下往上,每一行从右往左

返回值

dp[0][0]

实现代码

java 复制代码
class Solution {
    public int calculateMinimumHP(int[][] dungeon) {
        //1.创建dp表
        int m = dungeon.length;
        int n = dungeon[0].length;
        int[][] dp = new int[m+1][n+1];

        //2.初始化
        for(int row = 0; row < m+1; row++) {
            dp[row][n] = Integer.MAX_VALUE;
        }
        for(int col = 0; col < n+1; col++) {
            dp[m][col] = Integer.MAX_VALUE;
        }
        dp[m][n-1] = 1;

        //3.填表
        for(int i = m-1; i >= 0; i--) {
            for(int j = n-1; j >= 0; j--) {
                dp[i][j] = Math.min(dp[i+1][j], dp[i][j+1]) - dungeon[i][j];
                dp[i][j] = Math.max(1, dp[i][j]);
            }
        }
        //4.返回值
        return dp[0][0];
    }
}
相关推荐
legendary_bruce3 小时前
【22-决策树】
算法·决策树·机器学习
max5006004 小时前
基于桥梁三维模型的无人机检测路径规划系统设计与实现
前端·javascript·python·算法·无人机·easyui
快去睡觉~6 小时前
力扣400:第N位数字
数据结构·算法·leetcode
qqxhb7 小时前
零基础数据结构与算法——第七章:算法实践与工程应用-搜索引擎
算法·搜索引擎·tf-idf·倒排索引·pagerank·算法库
gzzeason8 小时前
LeetCode Hot100:递归穿透值传递问题
算法·leetcode·职场和发展
汤永红8 小时前
week1-[循环嵌套]画正方形
数据结构·c++·算法
pusue_the_sun8 小时前
数据结构——顺序表&&单链表oj详解
c语言·数据结构·算法·链表·顺序表
yi.Ist9 小时前
图论——Djikstra最短路
数据结构·学习·算法·图论·好难
数据爬坡ing9 小时前
过程设计工具深度解析-软件工程之详细设计(补充篇)
大数据·数据结构·算法·apache·软件工程·软件构建·设计语言
茜子.Java10 小时前
二分算法(模板)
算法