LeetCode question: 174. Dungeon game

Table of contents

1. Topic requirements

2. Problem-solving ideas

(1) Status indication

(2) State transition equation

(3) Initialize dp table

(4) Order of filling in the form

(5) Return value

3. Code


1. Topic requirements

174. Dungeon Game

The demons captured the princess and locked her in the dungeon lower right corner of the dungeon   . The dungeon is a two-dimensional grid composed of  rooms. Our heroic knight is initially placed in the upper left corner room where he must travel through the dungeon and save the princess by fighting the demon. m x n

The knight's initial health points are a positive integer. If his health points drop to 0 or below at any point, he dies instantly.

Some rooms are guarded by demons, so the knight will lose health points when entering these rooms (if the value in the room is a negative integer, means that the knight will lose health points); other rooms are either empty (the value in the room is 0), or contain magic that increases the knight's health points ball (if the value in the room is a positive integer, it means that the knight will increase health points).

In order to rescue the princess as soon as possible, the knight decided to only right or down Move one step.

Returns the minimum initial health points required to ensure the knight can save the princess.

Note:Any room may pose a threat to the knight's health points, or may increase the knight's health points, including the upper left room where the knight enters and the lower right corner where the princess is imprisoned Room.

Example 1:

Input:dungeon = [[-2,-3,3],[-5,-10,1],[10,30,-5]]
Output: 7
Explanation: If the knight follows the optimal path: right-> right-> down-> down, then the knight's initial health points are at least 7 . 

Example 2:

Import:dungeon = [[0]]
Exit: 1

2. Problem-solving ideas

We use the idea of ​​dynamic programming to analyze the problem. We have to go from the upper left corner to the lower right corner and find what our minimum initial health points are.

(1) Status indication

According to usual experience, we like to take a certain point as the end point and fill in the value of this position in the dp table, because here, if we take a certain point as the end point, the minimum number of health points required to get to this position from the front is After spending the health points before, I still have 1 health point left at this position, but I still have 1 health point left at this position. If I don't reach the lower right corner, I still have to walk many steps, and I will definitely die before I reach the lower right corner.

So, the state here represents:Define the minimum number of health points required to reach the lower right corner starting from a certain position.

(2) State transition equation

As shown in the picture:

We want to put a value in the four-pointed star position of the dp table. The value is the minimum number of health points required from the four-pointed star position to the lower right corner in the original table. Then, we know that each dp table places the current position. The minimum number of health points required to reach the lower right corner. Let the current point be The original table is d, and there is a newly created dp table,

So we derive:x + d[ i ][ j ] >= dp[ i + 1 ][ j ] or x + d[ i ][ j ] >= dp[ i ][ j + 1 ]

所以,x = dp[ i + 1 ][ j ] - d[ i ][ j ] 或 x = dp[ i ][ j + 1 ] - d[ i ][ j ]

Then we have to take the smallest value from the right or bottom. The number of health points needed to go to the next step is of course small enough to meet the requirements of the question.

combination:x = min(dp[ i + 1 ][ j ], dp[ i ][ j + 1 ]) - d[ i ][ j ]

Special case:If the current position is a large positive integer, that is, a large health pack, then x will be calculated as a negative number, which is not in line with our expectations. Because the number of points at the current position is a negative number, you can also go to the lower right corner, which does not meet the requirements of the question. Negative numbers have long been dead, so when our current x value is greater than 0, we do not process it, and x is still the original value. When the x value is less than or equal to 0, a 1 is placed at the current position. At least there is blood and you can continue going down.

Exit:Value of current position: max(1,x)

(3) Initialize dp table

According to the state representation we defined, we need to know the dp table values ​​below and on the left to deduce the current dp table value, so the last row and column may be out of bounds of the array, so we add the last row and column, And two positions are initialized to 1, and other positions are initialized to positive infinity, as shown in the figure:

Because, in order for the knight to reach the lower right corner, he must have at least 1 health point in the end before he can reach the lower right corner. This means that at least 1 health point is needed to reach the lower right corner. The other positions are initialized to positive infinity in order not to affect the last row and the last When filling out a form in one column, for example, in the last row, except for the lower right corner, you can only go to the right, and in the last column, you can only go down. So what we get is the dp value on the right, and the value on the right must be smaller than positive infinity.

(4) Order of filling in the form

From right to left, from bottom to top

(5) Return value

return dp[0][0]

3. Code

class Solution {
    public int calculateMinimumHP(int[][] dungeon) {
        //1、创建dp表
        int row = dungeon.length;//行
        int col = dungeon[0].length;//列
        int[][] dp = new int[row + 1][col + 1];
        //2、初始化dp表
        for(int i = 0; i < col + 1; i++) {
            //初始化最后一行
            dp[row][i] = Integer.MAX_VALUE;
        }
        dp[row][col - 1] = 1;//最后一行的特殊位置
        for(int i = 0; i < row + 1; i ++) {
            //初始化最后一列
            dp[i][col] = Integer.MAX_VALUE;
        }
        dp[row - 1][col] = 1;//最后一列的特殊位置
        //3、填dp表(顺序:从右到左,从下到上)
        for(int i = row - 1; i >= 0; i--) {
            for(int j = col - 1; j >= 0; j--) {
                int min = Math.min(dp[i + 1][j], dp[i][j + 1]) - dungeon[i][j];
                dp[i][j] = Math.max(1, min);
            }
        }
        //4、返回值
        return dp[0][0];
    }
}

Guess you like

Origin blog.csdn.net/cool_tao6/article/details/134885911