蓝桥杯数字三角形
數字三角形(進階版)
問題描述
   (圖3.1-1)示出了一個數字三角形。 請編一個程序計算從頂至底的某處的一條路
   徑,使該路徑所經過的數字的總和最大。
   ●每一步可沿左斜線向下或右斜線向下走;
   ●1<三角形行數≤100;
   ●三角形中的數字為整數0,1,…99;
 
 文件中首先讀到的是三角形的行數。
 接下來描述整個三角形
 輸出格式:
 最大總和(整數)
 樣例輸入
 5
 7
 3 8
 8 1 0
 2 7 4 4
 4 5 2 6 5
 樣例輸出
 30
 1、首先我們考慮能否使用搜索去做,因為每一步可沿左斜線向下或右斜線向下走,也就是說我們到達了一個位置(i,j),接著可以到達(i+1,j)或者(i+1,j+1);那么根據這個規律,就可以進行遞歸搜索,代碼如下:
復雜度很明顯是2的n次方,時間很容易超限
 原因分析如下:
 當我們要計算(i,j)這個位置時,這個位置是由(i-1,j)轉移過來的,我們已經求出了所有的(i.j)下面的位置,我們向上返回到(i-1,j)這個位置,我們向下就到達了(i,j+1)。我們發現(i,j)可以到達(i+1,j+1)并且(i,j+1)也可以到達(i+1,j+1)。那么(i+1,j+1)這個點我們就計算了兩次,會導致大量的重復計算,效率低下,導致時間超限。因此我們考慮,如果有一個數組用過來保存(i,j)能夠得到的最大值,那這樣我們就不用重復計算,那么就是把整個數組遍歷一遍,時間復雜度就是等差數組(n+1)*n/2,這樣時間復雜度就大大降低了。我們把這個方法叫做記憶化,這樣整個方法就叫做記憶化搜索。
接著優化,因為遞推要比遞歸快得多,因此平時我們要盡量將遞歸改造為遞推,我們之前f[i][j]表示的是從(i,j)出發能夠得到的最大的值,現在改造一下,將f[i][j]表示為從(1,1)出發到(i,j)能夠得到的最大的值。而這樣就能使用遞推,因為f[i][j] 可以由f[i-1][j-1] 和f[i-1][j]得到,而這就是一個遞推式,因此當我們計算(i,j)的時候只要保證(i-1,j-1)和(i-1,j)已經計算并且保存就行。而這種形式我們采用的是從上到下的順推形式。代碼如下:
#include <cstdio> #include <iostream> #include <cstring> #include <string> #include <algorithm> #include <math.h> using namespace std; int val[101][101]; int f[101][101]; int n,ans; int main() {memset(f,0,sizeof(f));//初始化數組f cin>>n;for(int i=1;i<=n;i++){for(int j=1;j<=i;j++){cin>>val[i][j];}} for(int i=1;i<=n;i++){for(int j=1;j<=i;j++){if(j==1){f[i][j]=val[i][j]+f[i-1][j];}else if(j==n){f[i][j]=val[i][j]+f[i-1][j-1];}else f[i][j]=max(f[i-1][j-1],f[i-1][j])+val[i][j];}}for(int i=1;i<=n;i++){ans=max(ans,f[n][i]);}cout<<ans;return 0;}接著我們繼續優化如果我們從上到下求最大值,轉化為從最后一排出發到達最后一層的最大值,那么對于(i,j)來說,可以從(i+1,j+1) (i+1,j)得到,那么我們就可以將整個遞推倒過來寫,省區最后的一個for循環
#include <cstdio> #include <iostream> #include <cstring> #include <string> #include <algorithm> #include <math.h> using namespace std; int val[101][101]; int f[101][101]; int n; int main() {memset(f,0,sizeof(f));cin>>n;for(int i=1;i<=n;i++){for(int j=1;j<=i;j++){cin>>val[i][j];}} for(int i=n;i>=1;i--){for(int j=1;j<=i;j++){f[i][j]=max(f[i+1][j+1],f[i+1][j])+val[i][j];}}cout<<f[1][1];return 0; }總結
 
                            
                        - 上一篇: rc52实现的部分代码
- 下一篇: WikiTaxi_Importer_1.
