【Leetcode每日一题】 动态规划 - 地下城游戏(难度⭐⭐⭐)(61)

这篇具有很好参考价值的文章主要介绍了【Leetcode每日一题】 动态规划 - 地下城游戏(难度⭐⭐⭐)(61)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1. 题目解析

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

【Leetcode每日一题】 动态规划 - 地下城游戏(难度⭐⭐⭐)(61),leetcode每日一题,算法,leetcode,动态规划,游戏,c++

这个问题的理解其实相当简单,只需看一下示例,基本就能明白其含义了。

2.算法原理

一、状态表定义

在解决地下城游戏问题时,我们首先需要对状态进行恰当的定义。一个直观的想法是,从起点开始,到达[i, j]位置时所需的最低初始健康点数。然而,这样的定义会导致状态转移时面临困难,因为当前位置的健康点数会受到后续路径的影响。

为了解决这个问题,我们采用另一种状态定义方式:从[i, j]位置出发,到达终点时所需的最低初始健康点数。这样定义的好处在于,当我们在[i, j]位置时,后续的最佳状态已经确定,从而可以顺利地进行状态转移。

因此,我们定义状态表dp如下:dp[i][j]表示从[i, j]位置出发,到达终点时所需的最低初始健康点数。

二、状态转移过程

在[i, j]位置,玩家有两种选择:向右走或向下走。我们需要根据这两种选择来推导dp[i][j]的值。

  1. 向右走到达下一个位置,然后从该位置继续到达终点。根据状态定义,这要求我们在[i, j]位置的最低健康点数加上当前位置的消耗,应大于等于右边位置的最低健康点数。即:x + dungeon[i][j] >= dp[i][j + 1]。通过移项,我们得到x的一个可能取值:x >= dp[i][j + 1] - dungeon[i][j]。

  2. 向下走到达下一个位置,然后从该位置继续到达终点。同样地,我们要求[i, j]位置的最低健康点数加上当前位置的消耗,应大于等于下边位置的最低健康点数。即:x + dungeon[i][j] >= dp[i + 1][j]。通过移项,我们得到x的另一个可能取值:x >= dp[i + 1][j] - dungeon[i][j]。

为了得到最小的初始健康点数,我们取这两种情况下的最小值作为dp[i][j]的候选值。因此,状态转移方程为:dp[i][j] = min(dp[i + 1][j], dp[i][j + 1]) - dungeon[i][j]。

然而,需要注意的是,如果当前位置的dungeon[i][j]是一个较大的正数,那么dp[i][j]的值可能会变成0或负数,这意味着最低点数会小于1,导致玩家死亡。因此,我们需要对dp[i][j]进行修正,确保其值至少为1。修正后的状态转移方程为:dp[i][j] = max(1, dp[i][j])。

三、初始化

为了正确地进行状态转移,我们需要对dp表进行初始化。一个常用的技巧是在dp表的最前面添加一行和一列辅助节点。这些辅助节点的值需要保证后续填表是正确的。在本题中,我们可以将所有辅助节点的值初始化为无穷大,然后设置dp[m][n - 1] = dp[m - 1][n] = 1,其中m和n分别是地图的行数和列数。

四、填表顺序

根据状态转移方程,我们需要从下往上逐行填写dp表,每行从左往右进行填写。这样的填表顺序可以确保在计算每个位置的dp值时,其右侧和下方的位置已经计算完毕,从而可以利用这些已知值进行状态转移。

五、返回值

最后,根据状态表定义,我们需要返回dp[0][0]的值,即从起点出发到达终点时所需的最低初始健康点数。

3.代码编写

class Solution 
{
public:
    int calculateMinimumHP(vector<vector<int>>& d) 
    {
        int m = d.size(), n = d[0].size();
        vector<vector<int>> dp(m + 1, vector<int>(n + 1, INT_MAX));
        dp[m][n - 1] = dp[m - 1][n] = 1;
        for(int i = m - 1; i >= 0; i--)
        {
            for(int j = n - 1; j >= 0; j--)
            {
                dp[i][j] = min(dp[i][j + 1], dp[i + 1][j]) - d[i][j];
                dp[i][j] = max(1, dp[i][j]);
            }
        }
        return dp[0][0];
    }
};

The Last

嗯,就是这样啦,文章到这里就结束啦,真心感谢你花时间来读。

觉得有点收获的话,不妨给我点个吧!

如果发现文章有啥漏洞或错误的地方,欢迎私信我或者在评论里提醒一声~文章来源地址https://www.toymoban.com/news/detail-861595.html

到了这里,关于【Leetcode每日一题】 动态规划 - 地下城游戏(难度⭐⭐⭐)(61)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • (动态规划) 132. 分割回文串 II ——【Leetcode每日一题】

    难度:困难 给你一个字符串 s ,请你将 s 分割成一些子串,使每个子串都是回文。 返回符合要求的 最少分割次数 。 示例 1: 输入:s = “aab” 输出:1 解释:只需一次分割就可将 s 分割成 [“aa”,“b”] 这样两个回文子串。 示例 2: 输入:s = “a” 输出:0 示例 3: 输入:

    2024年02月15日
    浏览(46)
  • 【Leetcode每日一题】模拟 - 数青蛙(难度⭐⭐)(54)

    1. 题目解析 题目链接:1419. 数青蛙 这个问题的理解其实相当简单,只需看一下示例,基本就能明白其含义了。 2.算法原理 一、模拟青蛙叫声的基本逻辑 在模拟青蛙叫声的过程中,我们需要遵循一定的规则来判断何时青蛙会发出声音。具体规则如下: 当遇到字符序列 \\\'r\\\'、

    2024年04月11日
    浏览(38)
  • (动态规划) 剑指 Offer 60. n个骰子的点数 ——【Leetcode每日一题】

    难度:中等 把 n 个骰子扔在地上,所有骰子朝上一面的点数之和为 s 。输入 n ,打印出s的所有可能的值出现的概率。 你需要用一个浮点数数组返回答案,其中第 i 个元素代表这 n 个骰子所能掷出的点数集合中第 i 小的那个的概率。 示例 1: 输入: 1 输出: [0.16667,0.16667,0.16667,

    2024年02月11日
    浏览(45)
  • ( 动态规划) 674. 最长连续递增序列 / 718. 最长重复子数组——【Leetcode每日一题】

    难度:简单 给定一个未经排序的整数数组,找到最长且 连续递增的子序列 ,并返回该序列的长度。 连续递增的子序列 可以由两个下标 l 和 r(l r) 确定,如果对于每个 l = i r ,都有 nums[i] nums[i + 1] ,那么子序列 [nums[l], nums[l + 1], ..., nums[r - 1], nums[r]] 就是连续递增子序列。

    2024年02月05日
    浏览(52)
  • (动态规划) 剑指 Offer 42. 连续子数组的最大和 ——【Leetcode每日一题】

    难度:简单 输入一个整型数组,数组中的一个或连续多个整数组成一个子数组。求所有子数组的和的最大值。 要求时间复杂度为 O(n) 。 示例1: 输入: nums = [-2,1,-3,4,-1,2,1,-5,4] 输出: 6 解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。 提示 : 1 = a r r . l e n g t h = 1 0 5 1 = arr.length = 10^

    2024年02月11日
    浏览(53)
  • Leetcode-每日一题【61.旋转链表】

    给你一个链表的头节点  head  ,旋转链表,将链表每个节点向右移动  k   个位置。 示例 1: 输入:head = [1,2,3,4,5], k = 2 输出:[4,5,1,2,3] 示例 2:   输入: head = [0,1,2], k = 4 输出: [2,0,1] 提示: 链表中节点的数目在范围  [0, 500]  内 -100 = Node.val = 100 0 = k = 2 * 109 1.根据题目给出

    2024年02月11日
    浏览(36)
  • (动态规划) 剑指 Offer 10- I. 斐波那契数列 ——【Leetcode每日一题】

    难度:简单 写一个函数,输入 n ,求斐波那契(Fibonacci)数列的第 n 项(即 F(N) )。斐波那契数列的定义如下: F(0) = 0, F(1) = 1 F(N) = F(N - 1) + F(N - 2), 其中 N 1. 斐波那契数列由 0 和 1 开始,之后的斐波那契数就是由之前的两数相加而得出。 答案需要取模 1e9+7(1000000007),如计

    2024年02月12日
    浏览(56)
  • 动态规划——地下城游戏

    leetcode在线oj题——地下城游戏 恶魔们抓住了公主并将她关在了地下城 dungeon 的 右下角 。地下城是由 m x n 个房间组成的二维网格。我们英勇的骑士最初被安置在 左上角 的房间里,他必须穿过地下城并通过对抗恶魔来拯救公主。 骑士的初始健康点数为一个正整数。如果他的

    2024年02月11日
    浏览(48)
  • (动态规划) 剑指 Offer 48. 最长不含重复字符的子字符串 ——【Leetcode每日一题】

    难度:中等 请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子字符串的长度。 示例 1: 输入: “abcabcbb” 输出: 3 解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。 示例 2: 输入: “bbbbb” 输出: 1 解释: 因为无重复字符的最长子串是 “b”,所

    2024年02月11日
    浏览(60)
  • 【LeetCode每日一题】2645. 构造有效字符串的最少插入数(计算组数+动态规划+考虑相邻字母)

    2024-1-11 2645. 构造有效字符串的最少插入数 方法一:计算组数 1.用count统计,能构成几组abc 2.如果当前字符大于之前字符,说明还在组内,不更新 3.如果当前字符小于等于之前字符,说明不是同一组的abc,组数更新 4.最终返回值:组数*3,再减去原本的字符数,就是要插入的次数

    2024年01月17日
    浏览(60)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包