hihocoder #1037 : 數字三角形 【動態規劃】

原址連接ios

時間限制:10000ms
單點時限:1000ms
內存限制:256MB算法

問題描述

小Hi和小Ho在經歷了螃蟹先生的任務以後被獎勵了一次出國旅遊的機會,因而他們來到了大洋彼岸的美國。美國人民的生活很是有意思,常常會有形形色色、奇奇怪怪的活動舉辦,這不,小Hi和小Ho剛剛下飛機,就遇上了當地的迷宮節活動。迷宮節裏展覽出來的迷宮都特別的有意思,可是小Ho卻相中了一個其實並不怎麼像迷宮的迷宮——由於這個迷宮的獎勵很是豐富~測試

因而小Ho找到了小Hi,讓小Hi幫助他獲取儘量多的獎品,小Hi把手一伸道:「迷宮的介紹拿來!」優化

小Ho選擇的迷宮是一個被稱爲「數字三角形」的n(n不超過200)層迷宮,這個迷宮的第i層有i個房間,分別編號爲1..i。除去最後一層的房間,每個房間都會有一些通往下一層的房間的樓梯,用符號來表示的話,就是從第i層的編號爲j的房間出發會有兩條路,一條通向第i+1層的編號爲j的房間,另外一條會通向第i+1層的編號爲j+1的房間,而最後一層的全部房間都只有一條離開迷宮的道路。這樣的道路都是單向的,也就是說當沿着這些道路前往下一層的房間或者離開迷宮以後,小Ho沒有辦法再次回到這個房間。迷宮裏同時只會有一個參與者,而在每一個參與者進入這個迷宮的時候,每一個房間裏都會生成必定數量的獎券,這些獎券能夠在經過迷宮以後兌換各類獎品。小Ho的起點在第1層的編號爲1的房間,如今小Ho悄悄向其餘參與者弄清楚了每一個房間裏的獎券數量,但願小Hi幫他計算出他最多能得到多少獎券。spa

提示一:盲目貪心不可取,搜索計算太耗時
提示二:記憶深搜逞神威,寬度優先解難題
提示三:總結概括提公式,減小冗餘是真理code

輸入

每一個測試點(輸入文件)有且僅有一組測試數據。遞歸

每組測試數據的第一行爲一個正整數n,表示這個迷宮的層數。內存

接下來的n行描述這個迷宮中每一個房間的獎券數,其中第i行的第j個數表明着迷宮第i層的編號爲j的房間中的獎券數量。ci

測試數據保證,有100%的數據知足n不超過100get

對於100%的數據,迷宮的層數n不超過100

對於100%的數據,每一個房間中的獎券數不超過1000

對於50%的數據,迷宮的層數不超過15(小Ho表示2^15才3萬多呢,也就是說……)

對於10%的數據,迷宮的層數不超過1(小Hi很好奇你的邊界狀況處理的如何?~)

對於10%的數據,迷宮的構造知足:對於90%以上的結點,左邊道路通向的房間中的獎券數比右邊道路通向的房間中的獎券數要多。

對於10%的數據,迷宮的構造知足:對於90%以上的結點,左邊道路通向的房間中的獎券數比右邊道路通向的房間中的獎券數要少。

輸出

對於每組測試數據,輸出一個整數Ans,表示小Ho能夠得到的最多獎券數。

樣例輸入

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

樣例輸出

28


個人評論:

一道簡單的動態規劃運用題。
動態規劃是一種對於遞歸算法的優化方法,典型的用空間換取時間思想。
第一步:分析問題,寫出遞歸式。遞歸中每每存在着對於同一個子問題的重複計算,這是動態規劃的着手點。
第二步:作好遞歸算法的條件分析,在計算結果時對於未計算過的問題進行存儲,對於已經計算過的問題直接使用存儲的結果。

#include <iostream>
using namespace std;
#define max2(a,b) ((a)>(b)?(a):(b))
#define max3(a,b,c) ((a)>(max2((b),(c)))?(a):(max2((b),(c))))
#define abs(a) ((a)>0?(a):(-(a)))
#define MAX 100000
#define MATRIXSIZE 201

int best[MATRIXSIZE][MATRIXSIZE]; // Note down the process solution.
int maze[MATRIXSIZE][MATRIXSIZE];
int n;
void initial_matrix()
{
    for(int i=0;i<MATRIXSIZE;i++){
        for(int j=0;j<MATRIXSIZE;j++)
            best[i][j] = MAX;
    }
}

// For test:
void print_maz()
{
    for(int i=0;i<n;i++){
        for(int j=0;j<n-i;j++)cout<<' ';
        for(int j=0;j<=i;j++) cout<<maze[i][j]<<' ';
        cout<<endl;
    }
}

int get_best(int i, int j)
{
    if(best[i][j]!=MAX)
    {
        return best[i][j];
    }
    else{
        if(i==0)
        {
            best[0][0]=maze[0][0];
            return best[0][0];
        }
        else if(j==0) {
            best[i][j] = get_best(i-1, j) + maze[i][j];
            return(best[i][j]);
        }
        else if(j>0){
            best[i][j] = max2(get_best(i-1,j-1), get_best(i-1, j)) + maze[i][j];
            return(best[i][j]);
        }
    }
}

int main()
{
    initial_matrix();
    cin>>n;
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<=i;j++)
            cin>>maze[i][j];
    }
    int biggest=0;
    for(int k=0;k<n;k++)
    {
        int best_at_ij = get_best(n-1,k);
        if(best_at_ij>biggest) biggest=best_at_ij;
    }
    cout<<biggest<<endl;
    return 0;
}
相關文章
相關標籤/搜索