【Dynamic Programming Upper Part Review】The minimum sum of the descending path | the maximum value of the gift


foreword

This article mainly discusses the minimum sum of the descending path of the dynamic programming idea and the maximum value of the gift.


1. Five parts of dynamic programming

  • 1. Determine the state representation (determine the meaning of the dp array)
  • 2. Determine the state transition equation (determine the recursive formula of dp)
  • 3. Determine how to initialize (initialize to ensure that the form is filled correctly)
  • 4. Determine the traversal order
  • 5. Return value

2. The minimum sum of the descending path

click me directly
insert image description here

Idea: dynamic programming solution

  • 1. Determine the state representation, that is, determine the meaning of the dp array.

    • When writing a dynamic programming topic, determining the state representation is the most important step. How to determine it? Experience + topic description is often required , which requires a lot of dynamic programming problem foundation.
      In this question, we need to use a two-dimensional dp array to represent the descending path, so the meaning of the dp array is: the
      minimum descending path at position [i, j] is dp[i][j].
  • 2. Determine the state transition equation (determine the recursive formula)

    • According to the title description, the position [i, j] is from any one of the three positions [i-1, j-1], [i-1, j], [i-1, j+1]. Come, as shown below.
      insert image description here
      So we can be sure that dp[i][j] must be related to dp[i-1][j-1], dp[i-1][j], dp[i-1][j+1].
      Let's look back at the meaning of the dp array: dp[i][j]: the minimum descending path at position [i, j] is dp[i][j],
      so when descending to position [i, j], it must be The minimum dp value of the three positions [i-1, j-1], [i-1, j], [i-1, j+1] + the path of the current position.
      That is: dp[i][j] = min(dp[i-1][j-1],dp[i-1][j],dp[i-1][j+1])+ob[i][j] , where ob is the two-dimensional array given in the title.
  • 3. How to initialize

    • Careful friends will find out, how is dp[0][j] derived from the data in the first row? If you only open up the dp array space of the size of the ob array given in the title, it cannot be completely initialized. So we give a solution to open up more virtual space. As shown in the figure below:
      insert image description here
      We open one more row and two columns of space, so that any position can be directly accessed.
      However, two issues need to be paid attention to when creating a virtual space:
      1. The initialization of the virtual position must ensure that the original dp array is correct.
      2. Pay attention to the mapping relationship of subscripts.
      • (1) We should initialize the first line of virtual space to 0, which ensures that the initialization of the original dp array is not affected.
        Reinitialize the first column and the n+1th column to positive infinity.
        insert image description here

Taking the numbers in the figure as an example, the position [i-1, j-1], that is, the position in the upper left corner is created virtually, so it must be ensured that the initialization of this position does not affect the initialization of the original array. So we should initialize to positive infinity at this dummy position. It is guaranteed that this place will never be taken.

      • (2) Pay attention to the mapping relationship of subscripts, take the above picture as an example, ,
        dp[i][j] = min(dp[i-1][j-1],dp[i-1][j],dp[i-1][j+1])+ob[i-1][j-1] note that here is +ob[i-1][j-1] instead of +ob[i][j], because the virtual array has an extra row and two columns , so the overall elements have moved a position to the lower right corner, so to find the original position, you must return to the upper left corner.
        insert image description here
  • 4. Determine the traversal order

    • According to the above description and the recursive formula, we can know that we can only traverse from top to bottom.
  • 5. Return value

    • When traversing to the last line, we should know that the title requires returning the minimum sum of the descending path. In the last line, each element is the smallest number of the descending path from top to bottom, so we should compare the elements in the last line The minimum value can be returned.

The specific code is as follows

class Solution {
    
    
public:
    int minFallingPathSum(vector<vector<int>>& ob) 
    {
    
    
        //1.确定dp[i][j]的含义:下降到i,j位置的最小路径为dp[i][j]
        //2.递推公式:
        //dp[i][j] = min(dp[i-1][j-1],dp[i-1][j],dp[i-1][j+1])+ob[i][j]        
        //3.初始化dp数组,多开一行,两列的虚拟空间,全部初始化为0
        //对虚拟空间的要求:1.里面的值要保证后面填表正确
        //2.要注意下标的映射
        //4.遍历顺序,只能从上到下遍历。
        //5.返回值,返回最后一行的最小值
        int n = ob.size();
        vector<vector<int>> dp(n+1,vector<int>(n+2,0));
        for(int i = 1;i<=n;i++)
        {
    
    
            dp[i][0] = INT_MAX;
            dp[i][n+1] = INT_MAX;
        }
//        vector<vector<int>> dp(n+1,vector<int>(n+2,INT_MAX));
        //第一行全部初始化成0,但是第一列和最后一列的第二行开始,就初始化成正无穷大
        // for(int i = 0;i< n+2;i++)
        // {
    
    
        //     dp[0][i] = 0;
        // }

        for(int i = 1;i<= n ;i++)
        {
    
    
            for(int j = 1;j<= n;j++)
            {
    
    
                dp[i][j] = min(dp[i-1][j-1],min(dp[i-1][j],dp[i-1][j+1]))+ob[i-1][j-1];        
            }
        }
        int ret = INT_MAX;
        //遍历dp表的最后一行,选出最小值
        for(int i = 1;i<=n;i++)
        {
    
    
            ret = min(ret,dp[n][i]);
        }
    }
};

时间复杂度O(n^2), 空间复杂度O(n^2)


3. The maximum value of the gift

click me directly~

insert image description here

Idea: dynamic programming

  • 1. State representation (determine the meaning of the dp array)
    According to experience and topic description,
    dp[i][j] means: the maximum value of the gift received at the [i,j] position is dp[i][j].
  • 2. State transition equation (determined recursive formula)
    insert image description here

It can be seen from the figure that walking to the [i, j]th position must be done by going down one step above it or one step from the left side to the right. So dp[i][j] must be related to dp[i-1][j] and dp[i][j-1].
Let’s review the meaning of the dp array again: the maximum value of the gift received at position [i,j] is dp[i][j]
Then we can determine the recursive formula:
dp[i][j] = max(dp[i-1][j],dp[i][j-1]) + grid[i][j], where grid is the array given in the title.
It can be found that the idea of ​​this question is similar to the previous one.

  • 3. How to initialize
    With the experience of the previous question, we found that the element in the first row cannot be initialized because it has no upper element and left element. Therefore, we should create more virtual arrays with one row and one column, as shown in the figure below:
    insert image description here
    Similarly: Two issues need to be paid attention to,
    1. The initialization of the virtual position must ensure that the original dp array is correct.
    2. Pay attention to the mapping relationship of subscripts.

So we should initialize it to 0, so that it will not be selected in the virtual space and will not affect the original array.

Then the mapping relationship of the subscript is also the same:
insert image description here
if you want to find the dp value of the position in the figure, it should be:
dp[i][j] = max(dp[i-1][j],dp[i][j-1]) + grid[i-1][j-1], because we have added an array with one row and one column, so the original array here has moved one bit to the lower right corner as a whole. To find the original value, you need to move back to the upper left corner to find it.

  • 4. Determine the initialization order
    From the above analysis, we can see that we should initialize from top to bottom and from left to right.

  • 5. Return value

  • Just return the value in the lower right corner.

The specific code is as follows:

class Solution {
    
    
public:
    int maxValue(vector<vector<int>>& grid) 
    {
    
    
        int m = grid.size();
        int n = grid[0].size();
        vector<vector<int>>dp(m+1,vector<int>(n+1));
        for(int i = 1;i<=m;i++)
        {
    
    
            for(int j = 1;j<=n;j++)
            {
    
    
                dp[i][j] = max(dp[i-1][j],dp[i][j-1]) + grid[i-1][j-1];
            }
        }
        return dp[m][n];
    }

};

时间复杂度O(m*n),空间复杂度O(m*n)

Summarize

Today I learned a dynamic programming point: open up an extra space to make the initialization easier, but also pay attention to two points:
1. The initialization of the virtual position must ensure that the original dp array is correct.
2. Pay attention to the mapping relationship of subscripts.

Guess you like

Origin blog.csdn.net/w2915w/article/details/131509605
Recommended