標籤:
Problem Description在講述DP演算法的時候,一個經典的例子就是數塔問題,它是這樣描述的:<br><br>有如下所示的數塔,要求從頂層走到底層,若每一步只能走到相鄰的結點,則經過的結點的數字之和最大是多少?<br><img src=../data/images/2084-1.jpg><br>已經告訴你了,這是個DP的題目,你能AC嗎?
Input輸入資料首先包括一個整數C,表示測試執行個體的個數,每個測試執行個體的第一行是一個整數N(1 <= N <= 100),表示數塔的高度,接下來用N行數字表示數塔,其中第i行有個i個整數,且所有的整數均在區間[0,99]內。<br>
Output對於每個測試執行個體,輸出可能得到的最大和,每個執行個體的輸出佔一行。<br>
Sample Input
1573 88 1 0 2 7 4 44 5 2 6 5
(1)題目大意:
本題講述的是經典數塔問題,就是相鄰的可以走,從頂層到底層,哪條路線權值相加是最大的。
(2)思路: 有兩種,一種是從上到下的走法,還有一種是從下到上的。我這裡是從下到上的,因為這個更簡便。用一個二維數組儲存該結構,我們發現從下到上,k層的每個值都對應k+1層的相鄰兩個值。所以我們取二者最大的給k層。以此類推,迴圈進行下去,第一層的值就是所有路徑最大值,槪題有點像貪心演算法。
(3)感想:
題目簡單,但是得需要仔細。對於一樣的題,任何方法可能都可以實現,但是步驟不一樣,因而就會有最優的,比如數塔,可以從上到下,但是你要判斷邊界問題,代碼不但長,而且運算時間夜場,不是最優的,相對的從下到上就更簡單方便。
(4)代碼:
#include<iostream>
using namespace std;
int main()
{
int n, m, c;
int a[100][100];//建立一個二維數組
cin >> c;//要測試的組數
int max(int m, int n);
while (c--)
{
cin >> n;//每組的行數
for (int i = 0;i < n;i++)
{
for (int j = 0;j <= i;j++)
{
cin>>a[i][j];//插入資料
}
}
//從下往上的加
for (int j = n - 2; j >= 0;j--)
{
for (int i = 0;i <= j;i++)
{
a[j][i] += max(a[j+1][i], a[j+1][i+1]);
}
}
cout << a[0][0] << endl;
}
return 0;
}
int max(int m, int n)
{
return m > n ? m : n;
}
acm專題三1006