• Leetcode 174. 地下城游戏(困难) 动态规划


    174. 地下城游戏(困难)

    题目:

    输入一个存储着整数的二维数组 grid,如果 grid[i][j] > 0,说明这个格子装着血瓶,经过它可以增加对应的生命值;如果 grid[i][j] == 0,则这是一个空格子,经过它不会发生任何事情;如果 grid[i][j] < 0,说明这个格子有怪物,经过它会损失对应的生命值。

    现在你是一名骑士,将会出现在最上角,公主被困在最右下角,你只能向右和向下移动,请问你初始至少需要多少生命值才能成功救出公主?

    换句话说,就是问你至少需要多少初始生命值,能够让骑士从最左上角移动到最右下角,且任何时候生命值都要大于 0。

    思路:

    从右下角往原点回走。记录每个点的血量最小值

    base case是dp[m-1][n-1]=max(0,-grid[m-1][n-1]),

    在遍历过程中,因为只能往右和往下走,所以要判断dp[i+1][j] 和dp[i][j+1]的大小,同时要记得过程中保持血量>0

    对于I==m-1和j==n-1的边上,则只能取右边和下边的值

    在最后的时候返回dp[0][0]+1。这样就是保持血量最低都为1.

    class Solution {
    public:
        int calculateMinimumHP(vector<vector<int>>& dungeon) {
            int m=dungeon.size();
            int n=dungeon[0].size();
            vector<vector<int>> dp(m,vector<int>(n));
            for(int i=m-1;i>=0;--i){
                for(int j=n-1;j>=0;--j){
                    //base case。到终点时只有1滴血。因为1在最后加,所以过程中保持dp>=0
                    if(i==m-1&&j==n-1){
                        dp[i][j]=max(0,-dungeon[i][j]);
                    }else if(i==m-1){
                        //对于底边,只能往右走
                        dp[i][j]=max(0,dp[i][j+1]-dungeon[i][j]);
                    }else if(j==n-1){
                        //对于右边界,只能往下走
                        dp[i][j]=max(0,dp[i+1][j]-dungeon[i][j]);
                    }else{
                        dp[i][j]=max(0,min(dp[i+1][j],dp[i][j+1])-dungeon[i][j]);
                    }
                }
            }
            //全程保持血量>=1
            return dp[0][0]+1;
        }
    };
  • 相关阅读:
    文件下载
    Regularexpressionvalidator控件常用正则表达式
    确认删除
    回发或回调参数无效。
    回车提交表单
    具有身份验证的web.config
    OleDbParameter参数的使用
    把CS文件编译成dll文件
    .Net简单三层
    ASP.NET 2.0中的页面输出缓存
  • 原文地址:https://www.cnblogs.com/zl1991/p/15952114.html
Copyright © 2020-2023  润新知