數字三角形,從遞歸到動態規划


 一.實踐題目
 
數字三角形 

給定一個由 n行數字組成的數字三角形如下圖所示。試設計一個算法,計算出從三角形 的頂至底的一條路徑(每一步可沿左斜線向下或右斜線向下),使該路徑經過的數字總和最大。

QQ截圖20170929023616.jpg

輸入格式:

輸入有n+1行:

第 1 行是數字三角形的行數 n,1<=n<=100。

接下來 n行是數字三角形各行中的數字。所有數字在0..99 之間。

輸出格式:

輸出最大路徑的值。

輸入樣例:

在這里給出一組輸入。例如:

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

輸出樣例:

在這里給出相應的輸出。例如:30



二.問題描述
  輸入數字三角形,從三角形頂點開始,每次只能在左右兩邊選擇路徑,每經過一個點取得該點數值,設計算法,求出和的最大的值。
三.算法描述
  使用自底向上遞推的方式,在每一行比較改行所有子問題的最優解,繼續往上計算,知道頂點,則比較出的則為最優解。
#include <iostream>
#define Max 101
using namespace std;
 
int n;
int a[Max][Max];  //用來存儲數字三角形的二維數組 
int MaxSum[Max][Max];//用來存儲第i行第j列到底邊的最大值 

int main(){
    //輸入數字三角形 
    cin >> n;
    for(int i=1;i<=n;++i)
        for(int j= 1;j<=i;++j)
            cin >> a[i][j];
            
    for(int i=1;i<=n;++i)
        MaxSum[n][i] = a[n][i];
        
    for(int i=n-1;i>=1;--i)   //自底向上計算 
        for(int j = 1;j<=n;++j)
            MaxSum[i][j] = (MaxSum[i+1][j] > MaxSum[i+1][j+1] ? MaxSum[i+1][j] : MaxSum[i+1][j+1]) + a[i][j];
            
    cout << MaxSum[1][1];
    return 0;
} 

四.算法時間及空間復雜度分析
  若采用遞歸算法,則時間復雜度為0(2^n),使用遞歸加備忘錄的方法,雖減少了對重復子問題的計算,但進棧出棧的時間、避免了棧溢出等問題仍沒有解決,動態規划算法使用雙重循環自底向上計算最優解,所以時間復雜度為O(n^2),
但新增二維數組保存每個子問題的解,空間復雜度為0(n^2)。

五.心得體會
1.與遞歸方法比,動態規划算法時間復雜度較低,且沒有棧溢出的風險,備忘錄方法雖解決了子問題重復計算的問題,但仍然有棧溢出風險。
2.遞歸方法、遞歸備忘錄方法都是自頂向下的算法,而動態規划算法是自頂向下的迭代算法,子問題只計算一次。
3.動態規划算法是用空間代價換取時間代價的算法。

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM