leetcode 174.地下城游戏

思路:dp。

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

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

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

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

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

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

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

另外,为什么要和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];
    }
};
相关推荐
先吃饱再说3 小时前
LeetCode 101. 对称二叉树
算法
是Dream呀3 小时前
人眼看不出的伪造,AI如何识别?实测合合信息跨模态鉴伪与去反光技术
算法
QN1幻化引擎3 小时前
SFA 信号场注意力:用8KB参数换248x KV Cache压缩,边缘设备也能跑长序列
人工智能·算法·gitee·gitlab
段一凡-华北理工大学4 小时前
向量数据库实战:选型、调优与落地~系列文章03:向量相似度算法全解:余弦、欧氏、内积,到底该用哪个?
大数据·数据库·人工智能·算法·机器学习·向量相似度·高炉炼铁
cjr_xyi5 小时前
AT1202Contest_c binarydigit 题解
c语言·c++·算法
atunet6 小时前
从算法优化到系统加速的多层级思考7
算法
Navigator_Z6 小时前
LeetCode //C - 1156. Swap For Longest Repeated Character Substring
c语言·算法·leetcode
Reart6 小时前
Leetcode 1143.最长公共子序列(720)
后端·算法
无相求码7 小时前
const vs #define:C语言常量定义的差异
c语言·算法
先吃饱再说7 小时前
LeetCode 226. 翻转二叉树
算法