LeetCode 174 Dungeon Game 题解

题意简述:有一个M*N的网格迷宫,位于左上角的骑士要到达右下角的公主的位置。每到达一个位置,骑士的生命值都会发生变化(负数为减少,正数为增加),如果在途中骑士的生命值降至0或以下,会立刻死亡。
假设骑士的生命值没有上限,而且每一步只能向右或者向下走。给定一个迷宫,那么骑士要安全到达右下角最少需要的初始生命值是多少。
输入:嵌套vector,代表迷宫每个网格骑士生命值的变化。
输出:一个int,代表最少需要的初始生命值。


题解:
对于每个网格只有两种选择,因此可以从终点右下角开始,向左向上递推出每个网格到达终点最少需要的初始生命值是多少,递推到起点左上角即可得到结果。
递推过程如下:

  • 右下角是递推的起始,只需要保证生命值加上网格的值大于等于1即可,如果网格的值为正,生命值1就可以;如果为负,需要加上网格的值的相反数。用公式表示就是:
    dp(m1,n1)=max(1dungeon(m1,n1), 1)
  • 对于最下边的一行,每个网格都只有向右走这一选择,由于右边的网格已经计算出最少需要的生命值,因此只有当前网格以及它右边的网格两个数值参与计算。
    dp(m1,j)=max(dp(m1,j+1)dungeon(m1,j), 1)(j=n2,n3,...,0)
  • 对于最右边的一列,每个网格都只有向下走这一选择,由于下边的网格已经计算出最少需要的生命值,因此只有当前网格以及它下边的网格两个数值参与计算。
    dp(i,n1)=max(dp(i+1,n1)dungeon(i,n1), 1)(i=m2,m3,...,0)
  • 对于其他网格,都有两种选择,取生命值更少的选择。
    dp(i,j)=max(min(dp(i+1,j),dp(i,j+1))dungeon(i,j), 1)

算法的时间复杂度和空间复杂度均为O(M*N)。

class Solution {
public:
    int calculateMinimumHP(vector<vector<int>>& dungeon) {
        int m = dungeon.size(), n = dungeon[0].size();

        vector<vector<int>> dp;
        for(int i = 0;i < dungeon.size();i++) {
            vector<int> temp;
            for(int j = 0; j < dungeon[0].size();j++)
                temp.push_back(0);
            dp.push_back(temp);
        }

        // border
        dp[m-1][n-1] = max(1-dungeon[m-1][n-1],1);
        for(int i = n-2;i >=0;i--)
            dp[m-1][i] = max(-dungeon[m-1][i] + dp[m-1][i+1],1);
        for(int i = m-2;i >=0;i--)
            dp[i][n-1] = max(-dungeon[i][n-1] + dp[i+1][n-1],1);

        // dp
        for(int i = m -2;i >= 0;i--) {
            for(int j = n -2;j >=0;j--) {
                dp[i][j] = max(-dungeon[i][j] + min(dp[i][j+1],dp[i+1][j]),1);
            }
        }

        return dp[0][0];
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值