經典問題: 數字三角形
73 8
8 1 0
2 7 4 4
4 5 2 6 5
在上面的數字三角形中尋找一條從頂部到底邊的路徑,使得路徑上所經過的數字之和最大。路徑上的每一步都只能往左下或 右下走。只需要求出這個最大和即可,不必給出具體路徑。 三角形的行數大於1小於等於100,數字為 0 - 99
很明顯,這道題的想法就是從最上面開始找一條路(如果採用暴力的方法會超時)
那麼我們該怎麼想這個問題呢。
首先 我們用 length(i,j)來代表 第i行第j列的元素(代表這個點的數字)比如 length(1,1)為 7
然後用 maxsum(i,j)代表 從這個點出發,到底邊的最大路徑
那麼我們可以知道
m ax
sum(
i,j)
=max
(max
sum(
i+1,
j),m
axsu
m(i+
1,j+
1))+
d(i,
j)
maxsum(i,j)=max(maxsum(i+1,j),maxsum(i+1,j+1))+d(i,j)
maxsum
(i,j
)=ma
x(ma
xsum
(i+1
,j),
maxs
um(i
+1,j
+1))
+d(i
,j)這就是狀態轉移方程了,從乙個點轉移到另乙個點。
從 m ax
sum(
i,j)
maxsum(i,j)
maxsum
(i,j
)這個問題 轉移到 求 max
sum(
i+1,
j)ma
xsum
(i+1
,j+1
)maxsum(i+1,j) maxsum(i+1,j+1)
maxsum
(i+1
,j)m
axsu
m(i+
1,j+
1)的子問題…
那麼我們很容易寫出遞迴程式:
int a[10]
[10];
//用來儲存每個點的數
intdp
(int x,
int y,
int n)
但是這種做法時間複雜度也很高,為什麼呢,因為他重複計算了一些點的數,而其實沒有必要重複算,我們只需要把之前計算過的值儲存下來,當再次被呼叫的時候直接返回值就可以了,而不需要進一步遞迴求值(這大大降低了時間複雜度,但是提高了空間複雜度——我們需要開乙個另外的陣列來儲存每個點的dp值)-> 其實這是記憶化搜尋,但是實質上都是動態規劃
**如下:
#include
using namespace std;
int a[10]
[10];
int sum[10]
[10]=
;intdp(
int x,
int y,
int n)
intmain()
dp 數字三角形問題
數字三角形問題 time limit 1000 ms memory limit 65536 kib problem description 給定乙個由n行數字組成的數字三角形如下圖所示。試設計乙個演算法,計算出從三角形的頂至底的一條路徑,使該路徑經過的數字總和最大。對於給定的由n行數字組成的數字三角...
數字三角形 DP
數字三角形 時間限制 10000ms 單點時限 1000ms 記憶體限制 256mb 問題描述 小hi和小ho在經歷了螃蟹先生的任務之後被獎勵了一次出國旅遊的機會,於是他們來到了大洋彼岸的美國。美國人民的生活非常有意思,經常會有形形色色 奇奇怪怪的活動舉辦,這不,小hi和小ho剛剛下飛機,就趕上了當...
(dp)數字三角形
數字三角形問題。有乙個由非負整數組成的三角形,第一行只有乙個數,除了最下行 之外每個數的左下方和右下方各有乙個數 從第一行的數開始,每次可以往左下或右下走一格,直到走到最下行,把沿途經過的數 全部加起來。如何走才能使得這個和盡量大?具體實現 中的d我們用maxsum表示 最初的位置我們用d存 1.把...