[Dynamic Programming Question 5] Minimum Path and && Dungeon Game

Minimum path sum

Link: 64. Minimum Path Sum

Given an mxn grid containing non-negative integers, find a path from the upper left corner to the lower right corner such that the sum of the numbers on the path is minimum.

Note: You can only move one step down or right at a time.

Insert image description here
Input: grid = [[1,3,1],[1,5,1],[4,2,1]]
Output: 7
Explanation: Because the sum of the path 1→3→1→1→1 is the smallest.

Example 2:
Input: grid = [[1,2,3],[4,5,6]]
Output: 12

1. Status representation

For this "path type" problem, our status representation generally has two forms:

  1. i. Starting from the position [i, j],...;
  2. ii. Starting from the starting position and arriving at the [i, j] position,...;

Here we choose the second way to define the state representation:
dp[i][j] means: the minimum path sum at the position [i, j].

2. State transition equation

For dp[i][j], we find that there are two ways to reach the position [i, j]:

  1. i. From the [i - 1, j] position above the [i, j] position, take one step downward and reach the [i, j] position;
  2. ii. From the [i, j - 1] position to the left of the [i, j] position, take one step to the right, and now reach the [i, j] position;

Since there are two situations to the [i, j] position, and what we are looking for is the minimum path, we only need the minimum value of these two situations, plus the own value at the [i, j] position, that is Can

dp[i][j] = min(dp[i - 1][j], dp[i][j - 1]) + grid[i][j]

3. Initialization

In order to solve some boundary conditions, we can add auxiliary nodes.
In this question, after "adding a row" and "adding a column", the values ​​of all positions can be initialized to infinity, and then let dp[0][1] = dp[1][0] = 1 is enough.

4. The order of filling in the form.
According to the "State Transfer Process", the order of filling in the form is "fill in each line from top to bottom" and "fill in each line from left to right".

5. Return value
The value of dp[m][n] should be returned;

Code:

   int minPathSum(vector<vector<int>>& grid) {
    
    
        int m=grid.size();
        int n=grid[0].size();
        vector<vector<int>> dp(m+1,vector<int>(n+1,INT_MAX));

        dp[0][1]=0;
        dp[1][0]=0;

        for(int i=1;i<=m;i++)
        {
    
    
            for(int j=1;j<=n;j++)
            {
    
    
                dp[i][j]=min(dp[i-1][j],dp[i][j-1])+grid[i-1][j-1];
            }
        }

        return dp[m][n];
    }

Insert image description here

174. Dungeon Game (###)

Links: 174. Dungeon Games

The demons captured the princess and imprisoned her in the lower right corner of the dungeon. A dungeon is a two-dimensional grid consisting of mxn rooms. Our heroic knight is initially placed in the upper left room, where he must travel through the dungeon and save the princess by fighting the demon.

The knight's initial health points are a positive integer. If his health points drop to 0 or below at any point, he will die immediately. 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, it means the knight will lose health points); other rooms are either empty (the value in the room is 0) , or contain a magic orb that increases the knight's health points (if the value in the room is a positive integer, it means the knight will increase his health points).

In order to rescue the princess as quickly as possible, the knight decided to move only one step to the right or down at a time.

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

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

Insert image description here

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

Example 2:
Input: dungeon = [[0]]
Output: 1

1. Status representation

If we define this question as: starting from the starting point and reaching the position [i, j], the minimum number of initial health points required.
Then there will be a problem when we analyze the state transition: that is, our current health points will also be affected by the subsequent paths . That is to say, state transfer from top to bottom cannot solve the problem well. (After-effect problem)
At this time, we need to change the state to represent: starting from the [i, j] position, the minimum initial health points required to reach the end point .
In this way, when we analyze the state transition, the subsequent optimal state is already known.
To sum up, the definition state is expressed as:
dp[i][j] means: starting from the position [i, j], the minimum initial health points required to reach the end point

2. State transition equation

For dp[i][j], starting from the position [i, j], there are two choices in the next step:

  1. Take a step to the right and reach the position of dp[i][j-1]. According to the definition of the dp[] array, the condition that needs to be met is that the life value when reaching dp[i][j-1] must be greater than Equal to dp[i][j-1], that is:
    dp[i][j] +dungeon[i][j]>=dp[i][j+1], ==》》dp[i][j] >=dp[i][j+1]-dungeon[i][j]

  2. Go one step down and reach the position of dp[i-1][j]. In the same way, we can get
    dp[i][j] >=dp[i+1][j]-dungeon[i][j]

To sum up, what we need is the minimum value in the two situations, so the available state transition equation is:
dp[i][j] = min(dp[i + 1][j], dp[i ][j + 1]) - dungeon[i][j]

However, if the dungeon[i][j] at the current position is a relatively large positive number, the value of dp[i][j] may become 0 or a negative number, that is, the lowest point number will be less than 1, then The rider will die. Therefore, if the dp[i][j] we find is less than or equal to 0, it means that the lowest initial value at this time should be 1. To handle this situation, you only need to let dp[i][j] and 1 take a maximum value:
dp[i][j] = max(1, dp[i][j])

3. Initialization

In order to solve some boundary conditions, we can add auxiliary nodes.
In this question, add a row at the end of the dp table and add a column. All values ​​are first initialized to infinity, and then let dp[m][n - 1] = dp[m - 1][n] = 1.

4. The order of filling in the form.
According to the "state transition process", we need to "fill in each row from bottom to top" and "fill in each row from right to left".

5. Return value
The value of dp[0][0] should be returned;

Code:

int calculateMinimumHP(vector<vector<int>>& dungeon) {
    
    
        int m=dungeon.size();
        int n=dungeon[0].size();

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

Insert image description here

Guess you like

Origin blog.csdn.net/m0_64579278/article/details/132124037