hihiocoder1037 數(shù)字三角形

題目:

時(shí)間限制:10000ms
單點(diǎn)時(shí)限:1000ms
內(nèi)存限制:256MB
問(wèn)題描述
小Hi和小Ho在經(jīng)歷了螃蟹先生的任務(wù)之后被獎(jiǎng)勵(lì)了一次出國(guó)旅游的機(jī)會(huì),于是他們來(lái)到了大洋彼岸的美國(guó)。美國(guó)人民的生活非常有意思,經(jīng)常會(huì)有形形色色、奇奇怪怪的活動(dòng)舉辦,這不,小Hi和小Ho剛剛下飛機(jī),就趕上了當(dāng)?shù)氐拿詫m節(jié)活動(dòng)。迷宮節(jié)里展覽出來(lái)的迷宮都特別的有意思,但是小Ho卻相中了一個(gè)其實(shí)并不怎么像迷宮的迷宮——因?yàn)檫@個(gè)迷宮的獎(jiǎng)勵(lì)非常豐富~
于是小Ho找到了小Hi,讓小Hi幫助他獲取盡可能多的獎(jiǎng)品,小Hi把手一伸道:“迷宮的介紹拿來(lái)!”
小Ho選擇的迷宮是一個(gè)被稱(chēng)為“數(shù)字三角形”的n(n不超過(guò)200)層迷宮,這個(gè)迷宮的第i層有i個(gè)房間,分別編號(hào)為1..i。除去最后一層的房間,每一個(gè)房間都會(huì)有一些通往下一層的房間的樓梯,用符號(hào)來(lái)表示的話(huà),就是從第i層的編號(hào)為j的房間出發(fā)會(huì)有兩條路,一條通向第i+1層的編號(hào)為j的房間,另一條會(huì)通向第i+1層的編號(hào)為j+1的房間,而最后一層的所有房間都只有一條離開(kāi)迷宮的道路。這樣的道路都是單向的,也就是說(shuō)當(dāng)沿著這些道路前往下一層的房間或者離開(kāi)迷宮之后,小Ho沒(méi)有辦法再次回到這個(gè)房間。迷宮里同時(shí)只會(huì)有一個(gè)參與者,而在每個(gè)參與者進(jìn)入這個(gè)迷宮的時(shí)候,每個(gè)房間里都會(huì)生成一定數(shù)量的獎(jiǎng)券,這些獎(jiǎng)券可以在通過(guò)迷宮之后兌換各種獎(jiǎng)品。小Ho的起點(diǎn)在第1層的編號(hào)為1的房間,現(xiàn)在小Ho悄悄向其他參與者弄清楚了每個(gè)房間里的獎(jiǎng)券數(shù)量,希望小Hi幫他計(jì)算出他最多能獲得多少獎(jiǎng)券。
提示一:盲目貪心不可取,搜索計(jì)算太耗時(shí)
提示二:記憶深搜逞神威,寬度優(yōu)先解難題
提示三:總結(jié)歸納提公式,減少冗余是真理
輸入
每個(gè)測(cè)試點(diǎn)(輸入文件)有且僅有一組測(cè)試數(shù)據(jù)。
每組測(cè)試數(shù)據(jù)的第一行為一個(gè)正整數(shù)n,表示這個(gè)迷宮的層數(shù)。
接下來(lái)的n行描述這個(gè)迷宮中每個(gè)房間的獎(jiǎng)券數(shù),其中第i行的第j個(gè)數(shù)代表著迷宮第i層的編號(hào)為j的房間中的獎(jiǎng)券數(shù)量。
測(cè)試數(shù)據(jù)保證,有100%的數(shù)據(jù)滿(mǎn)足n不超過(guò)100
對(duì)于100%的數(shù)據(jù),迷宮的層數(shù)n不超過(guò)100
對(duì)于100%的數(shù)據(jù),每個(gè)房間中的獎(jiǎng)券數(shù)不超過(guò)1000
對(duì)于50%的數(shù)據(jù),迷宮的層數(shù)不超過(guò)15(小Ho表示2^15才3萬(wàn)多呢,也就是說(shuō)……)
對(duì)于10%的數(shù)據(jù),迷宮的層數(shù)不超過(guò)1(小Hi很好奇你的邊界情況處理的如何?~)
對(duì)于10%的數(shù)據(jù),迷宮的構(gòu)造滿(mǎn)足:對(duì)于90%以上的結(jié)點(diǎn),左邊道路通向的房間中的獎(jiǎng)券數(shù)比右邊道路通向的房間中的獎(jiǎng)券數(shù)要多。
對(duì)于10%的數(shù)據(jù),迷宮的構(gòu)造滿(mǎn)足:對(duì)于90%以上的結(jié)點(diǎn),左邊道路通向的房間中的獎(jiǎng)券數(shù)比右邊道路通向的房間中的獎(jiǎng)券數(shù)要少。
輸出
對(duì)于每組測(cè)試數(shù)據(jù),輸出一個(gè)整數(shù)Ans,表示小Ho可以獲得的最多獎(jiǎng)券數(shù)。
樣例輸入
5
2
6 4
1 2 8
4 0 9 6
6 5 5 3 6
樣例輸出
28

這道題是數(shù)字三角形問(wèn)題,可以用動(dòng)態(tài)規(guī)劃的方法解決。
從每一個(gè)點(diǎn)(最后一行除外)到下一行的走法有兩種,假設(shè)該點(diǎn)為第i行第j列,則可以走到第i+1行第j列或者第i+1行第j+1列。如果暴力的話(huà)肯定過(guò)不了。但是我們可以發(fā)現(xiàn)第i行第j列到底端的數(shù)字之和取決于當(dāng)前第i行第j列的值以及第i+1行第j列到底端的數(shù)字之和和第i+1行第j+1列到底端的數(shù)字之和。因此我們可以得到一個(gè)狀態(tài)轉(zhuǎn)移方程式:
dp[i][j] = num[i][j] + max(dp[i+1][j], dp[i+1][j+1]);
最終的結(jié)果就是dp[1][1].

參考代碼:

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 100+5;

int mp[N][N];
int dp[N][N];//第i行第j個(gè)數(shù)到底端的數(shù)字之和的最大值;

void input(const int n) {
    for (int i = 1;i <= n;++i) {
        for (int j = 1;j <= i;++j) {
            cin >> mp[i][j];
        }
    }
}

int numtri(const int n) {//數(shù)字三角形 動(dòng)態(tài)規(guī)劃;
    for (int j = 1;j <= n;++j) {//從最后一層開(kāi)始向上遞推;
        dp[n][j] = mp[n][j];
    }

    for (int i = n-1;i >= 1;--i) {
        for (int j = 1;j <= i;++j) {
            dp[i][j] = mp[i][j] + max(dp[i+1][j], dp[i+1][j+1]);
        }
    }

    return dp[1][1];
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(NULL);

    int n;
    cin >> n;
    input(n);

    int ans = numtri(n);
    cout << ans << endl;
    return 0;
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容