1. 程式人生 > >經典演算法題:數字三角形尋找最大路徑

經典演算法題:數字三角形尋找最大路徑

題目:數字三角形,從頂部出發,在每一結點可以選擇向左走或得向右走,一直走到底層,要求找出一條路徑,該路徑上的數字和最大,輸出這個最大值。

(1)樣例輸入:
第一行是數塔層數N(1<=N<=100)。
第二行起,從一個數字按數塔圖形依次遞增,共有N層。
5
13
11 8
12 7 26
 6 14 15 8
12 7 13 24 11

思路:遞迴解決

用二維陣列 d[ l ][ r ] 存數字三角形

 if ( l  ==  n) maxSum( l , r ) = d [ l ][ r ] ;

 else maxSum ( l , r ) = max { maxSum( l+1, r ) , maxSum( l+1, r+1 ) }

很簡單呀

程式碼如下:

  1. #include <iostream>
  2. #include <algorithm>
  3. usingnamespace std;  
  4. #define MAX 101
  5. int d[MAX][MAX];  
  6. int n;  
  7. int MaxSum(int l,int r)  
  8. {  
  9.     if(l==n)  
  10.         return d[l][r];  
  11.     else
  12.         return max(MaxSum(l+1,r),MaxSum(l+1,r+1))+d[l][r];  
  13. }  
  14. int main()  
  15. {  
  16.     cin >> n;  
  17.     for
    (int i=1;i<=n;i++)  
  18.         for(int j=1;j<=i;j++)  
  19.             cin >> d[i][j];  
  20.     cout << MaxSum(1,1) << endl;  
  21.     return 0;  
  22. }  

好了,資料量大一點的時候,就華麗麗的超時了

分析一下時間複雜度,發現是 O(2^n),原因是

會 重 復 計 算 maxSum (r,l) 的值!

————————————————————————————————————————————————————————————————————————————

優化:(記憶遞迴型動態規劃)

思路:那就把計算結果存下來嘛。

程式碼如下:

  1. #include <iostream>
  2. #include <algorithm>
  3. usingnamespace std;  
  4. #define MAX 101
  5. int d[MAX][MAX];  
  6. int n;  
  7. int maxSum[MAX][MAX];  
  8. int MaxSum(int i,int j)  
  9. {  
  10.     if(maxSum[i][j]!=-1)  
  11.         return maxSum[i][j];  
  12.     if(i==n)  
  13.         maxSum[i][j] = d[i][j];  
  14.     else
  15.         maxSum[i][j] = max(MaxSum(i+1,j),MaxSum(i+1,j+1)) + d[i][j];  
  16.     return maxSum[i][j];  
  17. }  
  18. int main()  
  19. {  
  20.     cin >> n;  
  21.     for(int i=1;i<=n;i++)  
  22.         for(int j=1;j<=i;j++){  
  23.             cin >> d[i][j];  
  24.             maxSum[i][j]=-1;  
  25.         }  
  26.     cout << MaxSum(1,1) << endl;  
  27.     return 0;  
  28. }  

演算法時間複雜度成功變成 O(n^2);

不過遞迴還是慢一點,繼續優化! 


相關推薦

經典演算法數字三角形尋找路徑

題目:數字三角形,從頂部出發,在每一結點可以選擇向左走或得向右走,一直走到底層,要求找出一條路徑,該路徑上的數字和最大,輸出這個最大值。(1)樣例輸入:第一行是數塔層數N(1<=N<=100)。第二行起,從一個數字按數塔圖形依次遞增,共有N層。51311 812

數字三角形 計算路徑 動態規劃

以所經過的權值之和最大值為例進行說明。 行進的過程中,每次只有兩種選擇:向左或向右。一個有n層的數字三角形的完整路徑有2n條,所以當n比較大的時候,搜尋全部路徑,從中找出最大值,效率較低。 採用動態規劃方法實現。 用d(i,j)表示從位置(i,j)出發時得到的最大值(包括位置(i,j)本

經典演算法資料處理常見演算法

第一部分、十道海量資料處理 1、海量日誌資料,提取出某日訪問百度次數最多的那個IP。   此題,在我之前的一篇文章演算法裡頭有所提到,當時給出的方案是:IP的數目還是有限的,最多2^32個,所以可以考慮使用hash將ip直接存入記憶體,然後進行統計。  再詳細介紹下此方案:

經典演算法無序整數陣列中找第k的數

經典問題:寫一段程式,找出陣列中第k大的數,輸出數所在的位置。 【解法一】先排序,然後輸出第k個位置上的數 我們先假設元素的數量不大,例如在幾千個左右,在這種情況下,那我們就排序一下吧。在這裡,快速排序或堆排序都是不錯的選擇,他們的平均時間複雜度 都是 O(N * logN

經典演算法百錢買百雞

百錢買百雞的問題算是一套非常經典的不定方程的問題,題目很簡單:公雞5塊錢一隻,母雞3塊錢一隻,小雞3只一塊錢,用100快錢買一百隻雞,其中公雞,母雞,小雞都必須要有,問公雞,母雞,小雞要買多少隻剛好湊足100塊錢。分析:我們可以設公雞為x,母雞為y,小雞為z,那麼我們   

五分鐘學演算法經典演算法 排序演算法(某東演算法工程師比賽)

題目描述 已知資料表 A 中每個元素距其最終位置 不遠 ,為了節省時間,應該採取的演算法是() A、直接選擇排序 B、直接插入排序 C、堆排序 D、快速排序 題目分析 我們在之前學習 希爾排序 演算法的時候提及到,希爾排序進行到一定階段(每個元素距離其最終位置不遠時)一般都使用 插入排序 來收尾。 如果知

思考一道非相鄰數

 給定一個整數的陣列,相鄰的數不能同時選,求從該陣列選取若干整數,使得他們的和最大,要求只能使用o(1)的空間複雜度。 (抽時間再看看 )  // 非相鄰數最大和.cpp : 定義控制檯應用程式的入口點。 // #include "stdafx.h" #include

JAVA程式碼—演算法基礎子陣列的累加和問題

子陣列的最大累加和問題 JAVA程式碼實現 【問題描述】 給定一個一維陣列,返回子陣列的最大累加和。 例如,arraydemo=[1,-2,3,5,-2,6,-1];所有子陣列中,[3,5,-2,

演算法-兩個字串的公共子串

題目:給定一個query和一個text,均由小寫字母組成。要求在text中找出以同樣順序連續出現在query中最長連續字母序列的長度。例如,query為“acbac”,text為“acaccbabb”,那麼text中的“cba”為最長的連續出現在query中的字元序列,因此

經典演算法1找出陣列中只出現一次的數字,其它數字都出現了兩次

題目:一個整型數組裡除了一個數字之外,其它的數字都出現了兩次。請寫程式找出這個只出現一次的數字。要求時間複雜度是O(n),空間複雜度是O(1)。 分析:由於題目要求時間複雜度為O(n),所以先排序然後比較相鄰數字是否相同的思路被排除。             空間複雜度是O

演算法】計算機圖形學的一些經典判斷點在多邊形內,隨機生成三角形內的點,判斷兩個矩形是否相交等

前幾天面試的時候被問到了,如何隨機在三角形內生成點,我按照我的想法回答了一遍,但覺得回答的不夠好。最後面試官說了一個最優的方法。覺得不錯,順帶總結一下最近看到的一些關於計算機圖形學方面的經典小題,知乎上看到的還有Leetcode上的 1.判斷一個點

演算法(二十二)滑動視窗的

題目描述 給定一個數組和滑動視窗的大小,找出所有滑動窗口裡數值的最大值。例如,如果輸入陣列{2,3,4,2,6,2,5,1}及滑動視窗的大小3,那麼一共存在6個滑動視窗,他們的最大值分別為{4,4,6,6,6,5}; 針對陣列{2,3,4,2,6,2,5,1}的滑動視窗有以下6個: {[2,

演算法長迴文子串(C#實現)

給定一個字串 s,找到 s 中最長的迴文子串。你可以假設 s 的最大長度為 1000。 示例 1: 輸入: "babad" 輸出: "bab" 注意: "aba" 也是一個有效答案。 示例 2: 輸入: "cbbd" 輸出: "bb

java演算法只出現一次的數字

題目: 給定一個非空整數陣列,除了某個元素只出現一次以外,其餘每個元素均出現兩次。找出那個只出現了一次的元素。 說明: 你的演算法應該具有線性時間複雜度。 你可以不使用額外空間來實現嗎? 示例 1: 輸入: [2,2,1] 輸出: 1 示例 2: 輸入: [4,1,2,1

前端演算法找出陣列中第k數字出現多少次

題目:給定一個一維陣列,如[1,2,4,4,3,5],找出陣列中第k大的數字出現多少次。 例如:第2大的數是4,出現2次,最後輸出 4,2 function getNum(arr, k){ // 陣列排序-&gt;從大到小 arr.sort((a, b)=&gt;{

Google演算法二叉樹的深度

/** * Definition of TreeNode: * public class TreeNode { * public int val; * public TreeNode left, right; * public TreeNode(int val) { *

演算法學習之動態規劃--數字三角形路徑

題目: 7 3  8 8  1  0 2  7  4  4 4  5  2  6  5 在上面的數字三角形中尋找一條從頂部到底邊的路徑,使得路徑上所經過的數字之和最大。路徑上的每一步都只能往左下或右下走。只需要求出這個最大和即可,不必給出具體路徑。三角形的行數大於1小於

演算法愛好者——演算法間距 ? 待解決

給定一個未經排序的陣列,寫一個函式找出其排序表中連續兩個要素的最大間距。如果陣列中的要素少於 2 個,請返回 0。 注意事項: 1、可以假定陣列中的所有要素都是非負整數,且最大不超過 32 位整數。

Codility經典演算法之九MissingInteger

Task description:This is a demo task.Write a function:class Solution { public int solution(int[] A); }that, given an array A of N integers

經典演算法6貪心演算法小生成樹

 1、問題描述      設G =(V,E)是無向連通帶權圖,即一個網路。E中每條邊(v,w)的權為c[v][w]。如果G的子圖G’是一棵包含G的所有頂點的樹,則稱G’為G的生成樹。生成樹上各邊權的總和稱為該生成樹的耗費。在G的所有生成樹中,耗費最小的生成樹稱為G的最小