1. 程式人生 > 其它 >演算法學習->求解三角形最小路徑

演算法學習->求解三角形最小路徑

複習演算法設計與分析,動態規劃例題求解三角形最小路徑

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 };