Algorithm learning – > solve the minimum path of triangle and its value

Time:2022-1-14

 

00 question

00-1 description

For an integer triangle with a given height of N, find the minimum path sum from top to bottom. Each integer can only be moved down to the adjacent integer.

Find the same force deduction question:120. Triangle minimum path and force buckle (leetcode) (leetcode CN. Com)

Example 1:
Input: Triangle= [[2],[3,4],[6,5,7],[4,1,8,3]]
Output: 11
Explanation: as shown in the following diagram:
  2
 3 4
6 5 7
4 1 8 3
The minimum path sum from top to bottom is11(i.e., 2)+ 3 + 5 + 1 = 11)。
   
Example 2:
Input: Triangle= [[-10]]
Output:-10

00-2 prompt:

1 <= triangle.length <= 200
triangle[0].length == 1
triangle[i].length == triangle[i - 1].length + 1
-104 <= triangle[i][j] <= 104

01 ideas

If you want to write it with dynamic programming, the focus is on the state transition equation.

Abstract isosceles triangle into isosceles right triangle, as follows

  0 1 2 3
0 2
1 3 4
2 6 5 7
3 8 3 9 2

With the subscript sequence, we can consider the two-dimensional array DP. DP is the shortest path length used after storing to positions I and j, such as DP [2] [2] = 2 + 4 + 7 = 13

Define a starting point:

dp[0][0] = a[0][0];

Three cases:

  1. The triangle left road is the first column in the right angle diagram, which meets the following requirements:

    dp[i][0]=dp[i-1][0];
  2. Triangle right road, which is diagonal in the right angle diagram, meets the following requirements:

    dp[i][i]=dp[i-1][i-1]+a[i][i]
  3. Common location

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

So the program is easy to write. Just fill in the DP array and screen out the minimum value of the last row.

02 code

class Solution {
public:
   int minimumTotal(vector<vector<int>>& triangle) {
       int len = triangle.size();
       int dp[200][200]={0};
       dp[0][0]=triangle[0][0];
       for(int i=1;i<len;i++){
           dp[i][0] = dp[i-1][0]+triangle[i][0];
      }
       for(int i=1;i<len;i++){
           dp[i][i] = triangle[i][i]+dp[i-1][i-1];
      }
       for(int i=2;i<len;i++){
           for(int j=1;j<i;j++){
               dp[i][j] = triangle[i][j]+min(dp[i-1][j], dp[i-1][j-1]);
          }
      }
       //Fill DP
       //The following filter path is the shortest
       int ans = dp[len-1][0];
       for(int j = 1;j < len;j++){
           if(dp[len-1][j]<ans){
               ans = dp[len-1][j];
          }
      }
       return ans;
  }
};

03 Upgrade — Record path

03-1 ideas

If you want to write down the path, you need another two-dimensional array pre to record the previous node of the point with coordinates I and J. So how to record? Let’s take a look:

  • The previous node of (I, I) is (i-1, i-1);

  • The previous node of (I, J) is (i-1, J) or (i-1, J-1);

  • The previous node of (I, 0) is (i-1,0).

It is easy to conclude from these situations that the previous node must be I-1, and only the value of J needs to be recorded. Therefore, what we record in the pre two-dimensional array is the J value of the previous node of the current node.

After recording, we also need to output the minimum path. How to output?

On the basis of the previous problem, we get the column value of the minimum value of the last row, return it to the master function, and use it as a parameter to the path output function disppath.

The output method is:

  • For the current node, enter the stack, check its pre array value, update, and continue the operation until it is completed.

    The update operation is:

     path.push_back(a[i][k]);
    k=pre[i][k];
  • Stack one by one.

 

03-2 code

//Triangle minimum path
#include
#include
#include
using namespace std;
#define MAXN 100
int a[MAXN][MAXN];//Triangle
int n;//Height
int ans = 0;//Required path length
int dp[MAXN][MAXN];
int pre[MAXN][MAXN];//Precursor node
//According to the state transition equation, only the column number can be recorded
int Search(){
   int i,j;
   dp[0][0] = a[0][0];
   for(i=1;i<n;i++){
       dp[i][0]=dp[i-1][0]+a[i][0];
       pre[i][0]=i-1;
  }
   for(i=1;i<n;i++){
       dp[i][i]=dp[i-1][i-1]+a[i][i];
       pre[i][i]=i-1;
  }
   for(i=2;i<n;i++){
       for(j=1;j<i;j++){
           if(dp[i-1][j-1]<dp[i-1][j]){
               dp[i][j]=dp[i-1][j-1]+a[i][j];
               pre[i][j]=j-1;
          }
           else{
               dp[i][j]=dp[i-1][j]+a[i][j];
               pre[i][j]=j;          
          }
      }
  }
   ans = dp[n-1][0];
   int k=0;
   for ( j = 1; j < n; j++)
  {
       if(ans>dp[n-1][j]){
           ans = dp[n-1][j];
           k=j;
      }
  }
   return k;
}
void Disppath(int k){
   int i=n-1;
   vector<int>path;//Path node
   while(i>=0){
       path.push_back(a[i][k]);
       k=pre[i][k];
       i--;
  }
   vector<int>::reverse_iterator it;
   for(it=path.rbegin();it!=path.rend();++it){
       printf("%d ",*it);
  }
   printf("\n");
}

int main(){
   int k;//Triangles with K rows and K columns
   memset(pre, 0, sizeof(pre));
   memset(dp, 0, sizeof(dp));
   scanf("%d",&n);
   for(int i=0;i<n;i++){
       for(int j=0;j<=i;j++){
           scanf("%d",&a[i][j]);
      }
  }
   k=Search();
   Disppath(k);
   printf("%d\n",ans);
   return 0;
}