leetcode 174.地下城游戏

思路:dp。

原先的时候其实是想这样用dfs的做法进行解答的,但是呢,是不对的。

这里作者dfs的思路是:首先找出来最小路径和,然后再处理最小路径和这条路径里面的初始值。但是,后来发现这样不一定是最优解,因为当我们的路径和并不是最小值的时候,也可能得到最小的初始值。官方案例上应该已经给出来实例了。

从左上到右下,dp[i][j]的意思就是:从起点到(i,j)的最小初始值多少。这样的话我们需要考虑两个问题:1.我们现在走的路径和是多少,是不是最优解?2.我们现在走到的这条路径和是不是最小初始值?这样的话我们需要考虑这种两个值,递推的不现实,上面也说了,如果顾及到前者,后者不一定是最优。所以我们需要换一种思路。

如果说我们正向推导不行,那么我们或许可以试一试反向推导。也就是说,我们从右下向左上进行推导。这给我们提供一种思路,就是正向推导行不通的时候我们可以试一试反向推导。

反向推的话,我们的dp就变成了:从(i,j)到终点的最低初始值。这样的话,我们就不需要顾及到路径和的问题了。因为我们现在已经在(i,j)这个坐标里面了,那么前面的路径和一定是不小于当前的最低初始值的,也就是说我们已经定下来了路径和一定是合理的,所以我们就相当于只考虑最低初始值的问题了。那么我们就只推它了。

我们也知道,我们站在这个位置有两条路可以选:一个就是向下走,一个就是向右走。那么我们需要知道,这两个路我们需要走哪个?当然是选择其中小的一个,因为我们求的是最低初始值。这样的话,我们需要初始化dp,这样的话,我们就需要为dp数组赋值一个很大的值以至于我们可以取到最小值。

那么,状态方程就出来了:dp[i][j]=max(1,min(dp[i+1][j],dp[i][j+1])-dungeon[i][j])。看右边这子,为什么需要-dungeon[i][j]?由于我们还并没有走到下一步,并且还需要考虑到当前的值。

另外,为什么要和1作比较呢?我们从题目中可以知道,骑士的初始值并不能<=0。所以我们的初始值最低是1,所以如果右边这个式子<=0,那么我们就自动给它赋值成1.

上代码:

复制代码
class Solution {
public:
    int calculateMinimumHP(vector<vector<int>>& dungeon) {
        int n=dungeon.size();
        int m=dungeon[0].size();
        vector<vector<int>>dp(n+1,vector<int>(m+1,INT_MAX));
        dp[n-1][m]=dp[n][m-1]=1;
        for(int i=n-1;i>=0;i--){
            for(int j=m-1;j>=0;j--){
                int mins=min(dp[i+1][j],dp[i][j+1]);
                dp[i][j]=max(1,mins-dungeon[i][j]);
            }
        }
        return dp[0][0];
    }
};
相关推荐
SUNNY_SHUN24 分钟前
VLM走进农田:AgriChat覆盖3000+作物品类,607K农业视觉问答基准开源
论文阅读·人工智能·算法·开源
黎阳之光26 分钟前
视频孪生赋能车路云一体化,领跑智慧高速新征程
人工智能·算法·安全·数字孪生
Darkwanderor1 小时前
高精度计算——基础模板整理
c++·算法·高精度计算
普马萨特1 小时前
基站 / WiFi 粗略位置对 A-GNSS 的影响
网络·人工智能·算法
py有趣1 小时前
力扣热门100题之接雨水
算法·leetcode
mmz12072 小时前
深度优先搜索DFS(c++)
c++·算法·深度优先
汀、人工智能2 小时前
[特殊字符] 第103课:单词搜索II
数据结构·算法·均值算法·前缀树·trie·单词搜索ii
wanderist.3 小时前
算法模板-字符串
数据结构·算法·哈希算法
xiaoye-duck3 小时前
《算法题讲解指南:动态规划算法--子序列问题》--29.最长递增子序列的个数,30.最长数对链,31.最长定差子序列
c++·算法·动态规划
Yzzz-F3 小时前
Problem - 2180D - Codeforces
算法