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];
    }
};
相关推荐
寻找码源37 分钟前
【头歌实训:利用kmp算法求子串在主串中不重叠出现的次数】
c语言·数据结构·算法·字符串·kmp
Matlab精灵39 分钟前
Matlab科研绘图:自定义内置多款配色函数
算法·matlab
诚丞成1 小时前
滑动窗口篇——如行云流水般的高效解法与智能之道(1)
算法
带多刺的玫瑰2 小时前
Leecode刷题C语言之统计不是特殊数字的数字数量
java·c语言·算法
爱敲代码的憨仔2 小时前
《线性代数的本质》
线性代数·算法·决策树
yigan_Eins3 小时前
【数论】莫比乌斯函数及其反演
c++·经验分享·算法
阿史大杯茶3 小时前
AtCoder Beginner Contest 381(ABCDEF 题)视频讲解
数据结构·c++·算法
დ旧言~3 小时前
【高阶数据结构】图论
算法·深度优先·广度优先·宽度优先·推荐算法
张彦峰ZYF3 小时前
投资策略规划最优决策分析
分布式·算法·金融
The_Ticker4 小时前
CFD平台如何接入实时行情源
java·大数据·数据库·人工智能·算法·区块链·软件工程