[動態規劃] 五、三角形的最小路徑和

ajiang02發表於2020-02-20

題目

   2
  3 4
 6 5 7
4 1 8 3

如上所示,以上三角形由一連串的數字構成,要求從頂點 2 開始走到最底下邊的最短路徑,
每次只能向當前節點下面的兩個節點走,如 3 可以向 6 或 5 走,不能直接走到 7。
條件
三角形:一連串數字組成(用二維陣列儲存)
限制:只能向當前節點的下面兩個節點走

動態規劃問題建模階段

設三角形值為 value[ [2], [3,4], [6,5,7], [4,1,8,3] ]

底層      |   4   1   8   3
倒數第2|   7   6   10
倒數第3|   9  10
頂層      |  11

規律:
底層:一開始都是最小
倒數第二層:min(6+4, 6+1)=7、min(5+1, 5+8)=6、min(7+8,7+3)=10
倒數第三層:min(3+7, 3+6)=9、min(4+6, 4+10)=10
頂層:min(2+9, 2+10)=11

由此可見,只需要儲存前面的最小路徑數,就可推出後面的最小路徑數

動態規劃三個重要的概念

最優子結構:
由於有兩種走法,所以2往下走有兩種方案(選最小值)
2往下走 = min( 2+3, 2+4 )
邊界:
最底層 4,1,8,3 是最小的
轉態轉移公式:
d[i,j] = min(d[i+1,j], d[i+1,j+1]) + value[i,j]
(例:d[2,0] = min(d[3,0],d[3,1]) + value[2,0],即 d[2,0]=min(4,1)+6=7)

動態規劃求解問題階段

<?php

namespace app\index\controller;

// 動態規劃求解問題階段:
class Index
{
    /**
     * 動態規劃(Dynamic Programming)
     * 時間複雜度:O(n)
     * 空間複雜度:O(n)
     */
    public function test()
    {
        $value = [
            [2],
            [3,4],
            [6,5,7],
            [4,1,8,3]
        ];

        $value_len = count($value);         // 三角形的層數
        $min       = $value[$value_len-1];  // 初始值為陣列底層值

        // 迴圈三角形陣列,自底向上,從倒數第二層開始
        for ($i = $value_len - 2; $i >= 0; $i--) {

            $sub_len = count($value[$i]);   // 每層的長度

            // 迴圈每層的數字,從左到右
            for ($j = 0; $j < $sub_len; $j++) {
                $min[$j] = min($min[$j], $min[$j + 1]) + $value[$i][$j];
            }
        }
        echo $min[0];
    }
}

參考:動態規劃

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章