【LeetCode】Dynamic programming training (3)

931. Minimum Sum of Descending Paths

Click to view: The minimum sum of the descending path


Given an nxn square integer array matrix, please find and return the minimum sum of the descending paths through the matrix.
The descending path can start from any element in the first row and select an element from each row. The element selected in the next row is at most one column away from the element selected in the current row (i.e., the first element directly below or diagonally to the left or right). Specifically, the next element at position (row, col) should be (row + 1, col - 1), (row + 1, col) or (row + 1, col + 1).

Input: matrix = [[2,1,3],[6,5,4],[7,8,9]]
Output: 13
Explanation: As shown in the figure, there are two descending paths with minimum and

topic analysis

When at the (row, col) position, the next row can select the element at the (row+1, col) position / (row+1, col-1) position / (row+1, col+1) position

state transition equation

dp[i][j]: Indicates the minimum descending path from the position of the first row to the position [i, j]

Divide the problem according to the most recent step


[i, j] position can be moved down by [i-1, j-1] position / [i-1, j] position / [ i-1, j+1] position

So it can be divided into three situations:


The first case:
move down from position [i-1, j-1] to position [i, j]
If you want to get the minimum descending path at position [i, j], you should first get [i-1, The minimum descending path at position j-1] is dp[i-1, j-1]
plus the path at position [i, j] , that is, the position at [i, j] in the first case of ob[i, j]
The minimum descending path is: dp[i-1,j-1]+ob[i,j]


The second case:
move down from position [i-1, j] to position [i, j]
If you want to get the minimum descending path of position [i, j], you should get [i-1, j] first The minimum descending path of position is dp[i-1,j]
plus the path of [i,j] position is ob[i,j]
In the second case, the minimum descending path of position [i,j] is: dp [i-1,j]+ob[i,j]


The third case:
move down from the position [i-1, j+1] to the position [i, j]
If you want to get the minimum descending path of the position [i, j], you should first get [i-1, The minimum descending path at position j+1] is dp[i-1,j+1]
plus the path at position [i,j] is ob[i,j]
In the third case, the path at position [i,j] The minimum descending path is: dp[i-1,j+1]+ob[i,j]


State transition equation:
dp[i][j]= min( dp[i-1][j-1],dp[i-1][j],dp[i-1][j+1] )+ob (i,j);

full code

class Solution {
    
    
public:
    int minFallingPathSum(vector<vector<int>>& ob) {
    
    
       
       int m=ob.size();
       int n=ob[0].size();
       //dp数组 扩列一行 两列
       //并将 m+1 个 vetcor 数组 的n+2个值 都初始化为正无穷大
       vector<vector<int>>dp(m+1,vector<int>(n+2,INT_MAX));
       //将dp 扩列的第一行初始化为0
      // dp[0].resize(n+2,0);
      int i=0;
       int j=0;
      for(j=0;j<n+2;j++)
      {
    
    
          dp[0][j]=0;
      }
       
       for(i=1;i<=m;i++)
       {
    
    
           //从[1,1]位置开始到[i,n]位置结束
           for(j=1;j<=n;j++)
           {
    
    
               //ob作为原数组,dp作为扩列数组
               //使用dp扩列的下标 寻找ob对应的原数组下标 行需减1 列减1
               dp[i][j]= min(min(dp[i-1][j-1],dp[i-1][j]),dp[i-1][j+1])+ob[i-1][j-1];
           }
       }

     //寻找dp数组的最后一行的最小值
      int minsize=INT_MAX;
      for(j=1;j<=n;j++)
      {
    
    
         if(minsize>dp[m][j])
         {
    
    
             minsize=dp[m][j];
         }
      } 
     // 返回dp数组的最后一行的最小值
      return minsize;
    }
};

For the original array, using the state transition equation in the blue area will cause an out-of-bounds problem, so this problem is solved by expanding the column


The first row of the original array can only go from the current position to the current position, so the value of the original array element is stored
to protect the value of the first row of the original array, so the first row of the expanded array is all 0

If the position of the remaining expansion column is initialized to 0, it will interfere with the comparison result, so in order not to affect the selection, set its value to positive infinity


For example: 6 is the [i, j] position, if you want to get the minimum path, you need to search downwards, and you should get to the 2 position, but because
of the 0 that appears after the expansion, you will choose 0, which will lead to an error in the result

64. Minimum Path Sum

Click to view: minimum path and


Given a mxn grid of non-negative integers, find a path from the upper left corner to the lower right corner that minimizes the sum of numbers on the path.
Note: Only move down or right one step at a time.

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.

topic analysis

You can only go down or right each time
Find the minimum path from the upper left corner to the lower right corner and
the minimum path in the figure is: 1+3+1+1+1=7


state transition equation

dp[i][j]: Indicates the minimum path sum at this time from the starting position (upper left corner) to the position [i, j]

Divide the problem according to the most recent step


To get to position [i, j], you can only get one step down from position [i-1, j]
or one step to the right from position [i, j-1]

So dp[i][j] is divided into two cases:


The first one gets the [i, j] position downward from the [i-1, j] position

If you want to get the minimum path at position [i, j], you first need to get the minimum path at position [i-1, j], that is, dp[i-1, j]
plus the value of the original array ob corresponding to position [i, j] That is , the minimum path sum of the [i, j] position in the first case of ob [i, j] is: dp[i-1, j]+ob[i, j]


The second one takes a step to the right from the [i, j-1] position to get the [i, j] position

If you want to get the minimum path at position [i, j], you first need to get the minimum path at position [i, j-1], that is, dp[i, j-1]
plus the value of the original array ob corresponding to position [i, j] That is , the minimum path sum of the position [i, j] in the second case of ob[ i, j] is: dp[i, j-1]+ob[i, j]


The state transition equation is:
dp[i][j] = min( dp[i-1][j],dp[i][j-1] )+ob[i,j];

full code

class Solution {
    
    
public:
    int minPathSum(vector<vector<int>>& ob) {
    
    
          int m=ob.size();//行
          int n=ob[0].size();//列
          //将m+1个 vector数组 的n+1个值 设置为正无穷大
          //dp数组 将ob原数组 扩一行 和一列
          vector<vector<int>>dp(m+1,vector<int>(n+1,INT_MAX));
          int i=0;
          int j=0;
          //起点位置对应的上一个位置和左一个位置设置为0
          dp[0][1]=0;
          dp[1][0]=0;

          for(i=1;i<=m;i++)
          {
    
    
              for(j=1;j<=n;j++)
              {
    
    
                  //ob作为原数组 dp作为扩列数组
                  //通过扩列数组的下标 寻找原数组对应的下标 需行减1 列减1
                  dp[i][j]=min(dp[i-1][j],dp[i][j-1])+ob[i-1][j-1];
              }
          }
         // 由于dp是扩列数组 返回右下角 
          return dp[m][n];
          
    }
};

Initialization
If the state transition equation is used, the first row and first column of the original array may have an out-of-bounds problem, so in order to avoid this problem, expand the original array by one row and one column

insert image description here

Because there is no previous position or left position at this time, the value of the start position (start) of the dp array should be
the value . In order not to affect the result, the previous position corresponding to start and the left position are both set to 0


If the previous value of the red area is set to 0, when the state transition equation is performed, this 0 will be taken to interfere with the result,
so in order not to affect the result, set it to positive infinity


The remaining positions are also the same as the above one, which will interfere with the results, so in order to avoid affecting the results, they are all set to positive infinity

174. Dungeon Game

Click to view: Dungeon Game


The demons captured the princess and locked her in the lower right corner of the dungeon. A dungeon is a two-dimensional grid of mxn rooms. Our heroic knight is initially placed in the upper left room, and he must make his way through the dungeon and save the princess by fighting demons.
A knight's initial health points are a positive integer. If his health points drop to 0 or below at some 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, it means that the knight will lose health points); other rooms are either empty (the value in the room is 0) , or contain magic balls that increase the knight's health points (if the value in the room is a positive integer, it means that the knight will increase the health points).
In order to rescue the princess as soon as possible, the knight decided to move only one step to the right or down at a time.
Returns the minimum initial health points needed to ensure the knight can save the princess.

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.

topic analysis

Starting from the upper left corner and ending at the lower right corner,
you can only go down or right each time

-2 -> -3 -> 3 -> 1 -> -5


In the first room, 2 health points will be lost, so the knight needs 3 health points to get out of the first room, but at this time to enter the second room, 3 health points will be lost, the knight directly hangs Lost, so the initial 3 health points are not allowed

Walking out of the first two rooms requires the knight's initial health point to be 6 points (if the health point is 0, it will die). At this time, the knight's health point is 1 point
. 3 health points, changed to 4 points.
When the fourth room is finished, the knight adds 1 health point, which becomes 5 points.
When the last room is reached, 5 health points are lost, and the knight's health points are 0 , hung up directly

So the initial blood volume of the knight should be 7 points

state transition equation

Because it is judged by the initial blood volume, and is not only affected by the above but also behind,
it is necessary to use a certain position as the starting point to solve the problem

dp[i][j] means: starting from position [i,j] and reaching the end point, the stored value is the minimum required initial health points

Divide the problem according to the most recent step


[i, j] position, you can go down one step to reach [i+1, j] position or take one step to the right to reach [i, j+1] position

dp[i][j] is divided into two cases:


The first case is to move right from [i,j] position to [i,j+1] position

The health points from the position [i, j] can guarantee that the position [i, j+1] reaches the end point,
that is, dp[i][j] + ob[i][j] >= dp[i][j+ 1]
dp[i][j]>= dp[i][j+1]-ob[i][j]
and dp[i][j] is the minimum health point, so dp[i][j]= dp[i][j+1]-ob[i][j]


The second case is to move down from [i,j] position to [i+1,j] position

The health points from the [i,j] position can ensure that the [i+1,j] position reaches the end,
that is, dp[i][j] +ob[i][j] >= dp[i+1][ j]
dp[i][j]>= dp[i+1][j]-ob[i][j]
and dp[i][j] is the minimum health point, so dp[i][j]= dp[i+1][j]-ob[i][j]


The state transition equation is:
dp[i][j] = min(dp[i][j+1],dp[i+1][j])-ob[i][j];


If ob[i][j] is too large, resulting in a negative value of dp[i][j], it does not meet the requirements, because the minimum health point is 1

dp[i][j]=max(1,dp[i][j]);
If dp[i][j] is negative, replace it with 1

full code

class Solution {
    
    
public:
    int calculateMinimumHP(vector<vector<int>>& ob) {
    
    
      int m=ob.size();
      int n=ob[0].size();
      // 将 m+1个 vector 数组 的 n+1个值 都置为 正无穷大 
      vector<vector<int>>dp(m+1,vector<int>(n+1,INT_MAX));
     
    //从end位置走出来至少剩下1个健康点数
      dp[m-1][n]=1;
      dp[m][n-1]=1;
      int i=0;
      int j=0;
      for(i=m-1;i>=0;i--)
      {
    
    
          for(j=n-1;j>=0;j--)
          {
    
    
                dp[i][j]=min(dp[i][j+1],dp[i+1][j])-ob[i][j];
                //若dp[i][j]为负,将其置为1
                dp[i][j]=max(1,dp[i][j]);
          }
      }
      //dp[0][0]表示从起点位置开始,到终点至少需要多少初始健康点数
      return dp[0][0];
    }
};

Initialization
According to the state transition equation, both the last row and the rightmost row will trigger an out-of-bounds problem, so expand the original array by one row and one column

After walking out from the end position, there must be at least 1 health point left.
It is possible to take a step down, or take a step to the right.
The health points that come out from the [i, j] position can guarantee [i, j+1] position. to the end
so both positions are set to 1


The current position of the red area needs to be compared with the next position and the right position to take the smaller position,
but the position below is virtual, so it cannot be counted, otherwise it will interfere with the result,
so its position is set to positive infinity


The remaining positions are also the same as the above one, which will interfere with the results, so in order to avoid affecting the results, they are all set to positive infinity

Guess you like

Origin blog.csdn.net/qq_62939852/article/details/131368190