算法学习->求解三角形最小路径

00 问题

00-1 描述

对给定高度为n的一个整数三角形,找出从顶部到底部的最小路径和。每个整数只能向下移动到与之相邻的整数。

找到一个一样的力扣题:120. 三角形最小路径和 - 力扣(LeetCode) (leetcode-cn.com)

示例1:
输入:triangle = [[2],[3,4],[6,5,7],[4,1,8,3]]
输出:11
解释:如下面简图所示:
   2
  3 4
 6 5 7
4 1 8 3
自顶向下的最小路径和为 11(即,2 + 3 + 5 + 1 = 11)。
    
示例2:
输入:triangle = [[-10]]
输出:-10

 

00-2 提示:

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

01 思路

想用动态规划写出来,重点在于状态转移方程。

将等腰三角形抽象为等腰直角三角形,如下

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

加上下标化的序列,我们就可以用二维数组dp来考虑。dp是用来存储到i,j位置后用到的最短路径长度,比如dp[2] [2]=2+4+7=13

定义一个起点:

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

三种情况:

  1. 三角形左路,在直角图里就是第一列,满足:

    dp[i][0]=dp[i-1][0];
  2. 三角形右路,在直角图里是对角线,满足:

    dp[i][i]=dp[i-1][i-1]+a[i][i]
  3. 普通位置

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

     

这样程序就很好写了。就是往dp数组里填数就行,最后筛出最后一行的最小值就行。

02 代码

 1 class Solution {
 2 public:
 3     int minimumTotal(vector<vector<int>>& triangle) {
 4         int len = triangle.size();
 5         int dp[200][200]={0};
 6         dp[0][0]=triangle[0][0];
 7         for(int i=1;i<len;i++){
 8             dp[i][0] = dp[i-1][0]+triangle[i][0];
 9         }
10         for(int i=1;i<len;i++){
11             dp[i][i] = triangle[i][i]+dp[i-1][i-1];
12         }
13         for(int i=2;i<len;i++){
14             for(int j=1;j<i;j++){
15                 dp[i][j] = triangle[i][j]+min(dp[i-1][j], dp[i-1][j-1]);
16             }
17         }
18         //填充dp
19         //下面筛选路径最短
20         int ans = dp[len-1][0];
21         for(int j = 1;j < len;j++){
22             if(dp[len-1][j]<ans){
23                 ans = dp[len-1][j];
24             }
25         }
26         return ans;
27     }
28 };

 

 

posted @ 2021-11-04 23:30  climerecho  阅读(354)  评论(0编辑  收藏  举报