★問題描述:給字乙個由n行數字組成的數字三角形(等腰三角形)。試設計乙個演算法,計算出從三角形的頂至底的一條路徑,使該路徑經過的數字總和最大。
★演算法設計:對於給定的由n行數字組成的數字三角形,計算從三角形的項至底的路徑經過的數字和的最大值。
★資料輸入:由檔案input.txt提供輸入資料。檔案的第1行是數字三角形的計數n,1≤n≤100。接下來n行是數字三角形各行中的數字。所有數字在0~99之間。
★結果輸出:將計算結果輸出到檔案output.txt。檔案第1行中的數是計算出的最大值。
輸入檔案示例:input.txt 5
73 8
8 1 0
2 7 4 4
4 5 2 6 5
輸出檔案示例:output.txt 30
(1).輸入資料的儲存和表示:
先將數字三角形由乙個等腰變形為乙個直角三角形,便於我們使用矩陣來儲存和表示。
矩陣表示如下:
0 0 0 0 0 0
0 7 0 0 0 0
0 3 8 0 0 0
0 8 1 0 0 0
0 2 7 4 4 0
0 4 5 2 6 5
相應輸入部分的**:
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++) }
(2).解題思路
基本思路--採用自頂向下的方法
a.思路一:自頂向下依次遍歷,在碰到分叉路的時候選擇較大的數。(錯誤--區域性最優並不等於整體最優)
比如上述例題按這種方法得到的「最優解」:7+8+1+7+5=27
而實際上的最優解:7+3+8+7+5=30
b.思路二:自頂向下依次遍歷,列舉出所有路徑的大小,最後再進行比較。(正確)
儲存資料:首先,我們需要乙個矩陣儲存當前路徑的大小,這裡我們使用nt(number ********)儲存原來的數字三角形,使用st(sum ********)儲存當前路徑的大小。由於每個路徑資料再往下發展的時候都有兩種可能,因此這個矩陣的大小為n*2(n-1),這裡的話我直接使用了2n。
演算法設計:
初始化,st[i][0]=0;st[0][j]=0;st[1][1]=nt[1][1]
自頂向下遍歷
當前路徑的和=上一層路徑的和+當前資料;
r[1][1]=a[1][1];
for(int i=2;i<=n;i++) }
遍歷結束後,st的資料儲存情況
10就是路徑:7+3的和;
15就是路徑:7+8的和; 等等
回溯最優路徑:
由於我們在計算最優路徑時,用st儲存了所有當前路徑的大小。因此我們只需要用最後的最優路徑的數值依次往回減就可以求出最優路徑了。由於我們的回溯是自底向上,路徑的資料順序是倒著的。因此這裡使用了棧來儲存路徑資料,利用其後進先出的特點回溯出最優路徑。
#include#include#include#includeusing namespace std;
//計算數字三角形最大路徑的值
int numtri(int n,int **a,int **r) }}
//回溯最優路徑
在做動態規劃這一類問題時一定要注意很多時候區域性最優解並不等於整體最優解。
動態規劃 數字三角形問題
數字三角形問題 time limit 1000ms memory limit 65536kb problem description 給定乙個由n行數字組成的數字三角形如下圖所示。試設計乙個演算法,計算出從三角形的頂至底的一條路徑,使該路徑經過的數字總和最大。對於給定的由n行數字組成的數字三角形,計...
動態規劃 數字三角形問題
有乙個由非負整數組成的三角形,第一行只有乙個數,除了最下行之外每個數的左下方和右下方各有乙個數.3 24 10 1 4 3 2 20 從第一行的數開始,每次可以往左下或右下走一格,直到走到最下行,把沿途經過的數全部加起來,如何走才能使得這個和盡量大?輸入 三角形的行數n,數字三角形的各個數 從上到下...
動態規劃 數字三角形問題
problem description 給定乙個由n行數字組成的數字三角形如下圖所示。試設計乙個演算法,計算出從三角形的頂至底的一條路徑,使該路徑經過的數字總和最大。對於給定的由n行數字組成的數字三角形,計算從三角形的頂至底的路徑經過的數字和的最大值。input 輸入資料的第1行是數字三角形的行數n...