• leetcode 174


    /*
     * @lc app=leetcode id=174 lang=cpp
     *
     * [174] Dungeon Game
     *
     * https://leetcode.com/problems/dungeon-game/description/
     *
     * algorithms
     * Hard (26.59%)
     * Total Accepted:    64.1K
     * Total Submissions: 239.1K
     * Testcase Example:  '[[-2,-3,3],[-5,-10,1],[10,30,-5]]'
     *
     * table.dungeon, .dungeon th, .dungeon td {
     * ⁠ border:3px solid black;
     * }
     * 
     * ⁠.dungeon th, .dungeon td {
     * ⁠   text-align: center;
     * ⁠   height: 70px;
     * ⁠    70px;
     * }
     * 
     * The demons had captured the princess (P) and imprisoned her in the
     * bottom-right corner of a dungeon. The dungeon consists of M x N rooms laid
     * out in a 2D grid. Our valiant knight (K) was initially positioned in the
     * top-left room and must fight his way through the dungeon to rescue the
     * princess.
     * 
     * The knight has an initial health point represented by a positive integer. If
     * at any point his health point drops to 0 or below, he dies immediately.
     * 
     * Some of the rooms are guarded by demons, so the knight loses health
     * (negative integers) upon entering these rooms; other rooms are either empty
     * (0's) or contain magic orbs that increase the knight's health (positive
     * integers).
     * 
     * In order to reach the princess as quickly as possible, the knight decides to
     * move only rightward or downward in each step.
     * 
     * 
     * 
     * Write a function to determine the knight's minimum initial health so that he
     * is able to rescue the princess.
     * 
     * For example, given the dungeon below, the initial health of the knight must
     * be at least 7 if he follows the optimal path RIGHT-> RIGHT -> DOWN ->
     * DOWN.
     * 
     * 
     * 
     * 
     * -2 (K)
     * -3
     * 3
     * 
     * 
     * -5
     * -10
     * 1
     * 
     * 
     * 10
     * 30
     * -5 (P)
     * 
     * 
     * 
     * 
     * 
     * 
     * Note:
     * 
     * 
     * The knight's health has no upper bound.
     * Any room can contain threats or power-ups, even the first room the knight
     * enters and the bottom-right room where the princess is imprisoned.
     * 
     * 
     */
    
    #include<vector>
    #include<iostream>
    #include<cmath>
    #include<limits.h>
    
    #define min(a,b) (a>b?b:a)
    #define max(a,b) (a<b?b:a)
    
    class Solution {
    public:
        int calculateMinimumHP(std::vector<std::vector<int>>& dungeon) {
            int minHP = INT_MIN;
            int row = dungeon.size();
            int col = dungeon[0].size();
            int tmp;
            std::vector<std::vector<int>> mem(row,std::vector<int>(col));     
            mem[row-1][col-1] = dungeon[row-1][col-1]<0 ? dungeon[row-1][col-1] : 0;
            for(int i = row -2;i >= 0; --i){
                mem[i][col-1] = dungeon[i][col-1] > 0 ? min(dungeon[i][col-1]+ mem[i+1][col-1],0) : dungeon[i][col-1]+ mem[i+1][col-1];            
            }
            for(int j = col - 2;j >=0 ; --j){
                mem[row - 1][j] = dungeon[row-1][j] > 0 ? min(dungeon[row-1][j] + mem[row-1][j+1],0) : dungeon[row-1][j] + mem[row-1][j+1]; 
            }
            for(int i = row - 2;i >= 0; --i){
                for(int j = col - 2;j >= 0; --j){
    
                    mem[i][j] = dungeon[i][j] > 0 ?
                                min(max(mem[i+1][j], mem[i][j+1]) + dungeon[i][j],0) :
                                max( mem[i+1][j] , mem[i][j+1] ) + dungeon[i][j];
                }
                // minHP = dungeon[i][j];
            }
            // for(int i = 0;i < row;++i){
            //     for(int j = 0;j<col;++j){
            //         std::cout<<mem[i][j]<<'	';
            //     }
            //     std::cout<<std::endl;
            // }
            return -mem[0][0] + 1;        
        }
    };
    
    
    int main()
    {
        Solution s;
        std::vector<std::vector<int>> tmp = {{1,-4,5,-99},{2,-2,-2,-1}};
        std::cout<<s.calculateMinimumHP(tmp)<<std::endl;
        return 0;
    }
    
    

    主要存在的问题,这里一定要明确的一点是,我们从左上角出发,前进过程中,每一个格子的最小生命值是由后面的路径所决定的,因此,不能从左上角开始规划,要从右下角开始;
    二是在前进过程中,每一个点的最小生命值是由之后的最小生命值和当前的格子决定的,并且需要比较右和坐两个方向。

    class Solution {
    public:
        int calculateMinimumHP(std::vector<std::vector<int>>& dungeon) {
            int minHP = INT_MIN;
            int row = dungeon.size();
            int col = dungeon[0].size();
            int tmp;
            if(dungeon[row-1][col-1]>0) dungeon[row-1][col-1] = 0;
            //the last col
            for(int i = row -2;i >= 0; --i){                
                dungeon[i][col-1] = dungeon[i][col-1] > 0 ? min(dungeon[i][col-1]+ dungeon[i+1][col-1],0) : dungeon[i][col-1]+ dungeon[i+1][col-1];            
            }
            // printVectorInt(dungeon);
            //the last row
            for(int j = col - 2;j >=0 ; --j){
                dungeon[row - 1][j] = dungeon[row-1][j] > 0 ? min(dungeon[row-1][j] + dungeon[row-1][j+1],0) : dungeon[row-1][j] + dungeon[row-1][j+1]; 
            }
            // printVectorInt(dungeon);
            for(int i = row - 2;i >= 0; --i){
                for(int j = col - 2;j >= 0; --j){
                    dungeon[i][j] = dungeon[i][j] > 0 ?
                                min(max(dungeon[i+1][j], dungeon[i][j+1]) + dungeon[i][j],0) :
                                max( dungeon[i+1][j] , dungeon[i][j+1] ) + dungeon[i][j];
                }
                // minHP = dungeon[i][j];
            }
            // printVectorInt(dungeon);
            return -dungeon[0][0] + 1;        
        }
        void printVectorInt(std::vector<std::vector<int>>& dungeon){
            int row = dungeon.size();
            int col = dungeon[0].size();
            for(int i = 0;i < row;++i){
                for(int j = 0;j<col;++j){
                    std::cout<<dungeon[i][j]<<'	';
                }
                std::cout<<std::endl;
            }
        }
    };
    

    在原数组上操作,能减少一点内存,但效果不明显。

  • 相关阅读:
    初学Google Code,Subversion和TortoiseSVN
    成长,真有你想象的那样迫切?
    Java中十个常见的违规编码
    Eclipse打包工具Fatjar
    “旁观者效应”是如何毁掉我们的代码的
    java设计模式—分类
    java中的关键字static(静态变量)和final定义常量
    JAVA UDP打洞必备知识点NAT
    [Struts]在jsp里处理比较复杂的内容?
    反向链接referrer的原理
  • 原文地址:https://www.cnblogs.com/walnuttree/p/10729064.html
Copyright © 2020-2023  润新知