hdu2084數塔

Wood_Du發表於2018-03-13

遞推問題(簡單):
有如下所示的數塔,要求從頂層走到底層,若每一步只能走到相鄰的結點,則經過的結點的數字之和最大是多少?
這裡寫圖片描述

已經告訴你了,這是個DP的題目,你能AC嗎?

Input

輸入資料首先包括一個整數C,表示測試例項的個數,每個測試例項的第一行是一個整數N(1 <= N <= 100),表示數塔的高度,接下來用N行數字表示數塔,其中第i行有個i個整數,且所有的整數均在區間[0,99]內。

Output

對於每個測試例項,輸出可能得到的最大和,每個例項的輸出佔一行。

Sample Input

1
5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5

Sample Output

30

解題思路:
就是要從下往上看。舉個例子(根據圖):
如果你從上到下走到了第4行第1個數,也就是2,那麼接下來有兩個數可以走19和7,
而你必然會選擇19。所以就可以根據這個思路更新上面一行的數。把2更新成2+19=21。18更新成18+10=28,9更新成9+10=19,5更新成5+16=21

num[4][0]=2+19; num[4][1]=18+10; num[4][2]=9+10; num[4][3]=5+16;
num[4][0]=10+(18+10); num[4][1]=6+(18+10); num[4][2]=8+(5+16);
num[4][0]=12+max(); num[4][1]=15+max();
num[4][0]=9+max();

重複上面的思路最後第一行累加出來的就是最大值了。使用原陣列的最後一行來儲存資料,
把累加的情況一直作用在最後一行。
那麼最後一行的第一個數就是最大值。最後結果為num[n-1][0]

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
using namespace std;

int main(){
int T,n,num[110][110];
scanf("%d",&T);
while(T--){
    scanf("%d",&n);
    for(int i=0;i<n;i++){
        for(int j=0;j<=i;j++){
            scanf("%d",&num[i][j]);
        }
    }
    for(int i=n-2;i>=0;i--){
        for(int j=0;j<=i;j++){//j<=i;因為第3(i)行有4(i+1)個數  最終結果為num[n-1][0]
            if(num[i][j]+num[n-1][j]>num[i][j]+num[n-1][j+1]){
                num[n-1][j]=num[i][j]+num[n-1][j];
            }
            else{
                num[n-1][j]=num[i][j]+num[n-1][j+1];
            }
        }
    }

printf("%d\n",num[n-1][0]);
}
return 0;
}

相關文章