P1434 [SHOI2002]滑雪 記憶化搜索+遞歸

題目描述

Michael 喜歡滑雪。這並不奇怪,由於滑雪的確很刺激。但是爲了得到速度,滑的區域必須向下傾斜,並且當你滑到坡底,你不得再也不次走上坡或者等待升降機來載你。Michael 想知道在一個區域中最長的滑坡。區域由一個二維數組給出。數組的每一個數字表明點的高度。下面是一個例子:html

1 2 3 4 5 16 17 18 19 6 15 24 25 20 7 14 23 22 21 8 13 12 11 10 9 

一我的能夠從某個點滑向上下左右相鄰四個點之一,當且僅當高度會減少。在上面的例子中,一條可行的滑坡爲 2424-1717-1616-11(從 2424 開始,在 11 結束)。固然 2525-2424-2323-\ldots…-33-22-11 更長。事實上,這是最長的一條。ios

輸入格式

輸入的第一行爲表示區域的二維數組的行數 RR 和列數 CC。下面是 RR 行,每行有 CC 個數,表明高度(兩個數字之間用 11 個空格間隔)。數組

輸出格式

輸出區域中最長滑坡的長度。spa

輸入輸出樣例

輸入 #1
5 5
1 2 3 4 5
16 17 18 19 6
15 24 25 20 7
14 23 22 21 8
13 12 11 10 9
輸出 #1
25

說明/提示

對於 100\%100% 的數據,1\leq R,C\leq 1001R,C100。code

 

一開始很懵逼,用遞歸寫了老半天,覺得最長的就是從最高的地方滑雪,圖樣圖僧破orm

後來寫出了一個海星的遞歸,結果LTE了。看題解才知道有記憶化搜索這種東西,因而又寫了一遍。htm

#include <iostream>
#include <algorithm>
using namespace std;
#define maxn 9999999
int d[105][105];
int maxd = -1;
int mind = maxn;
int max_r, max_c;
int min_r, min_c;
int s[106][105];
//int m1,m2,m3,m4;
int m, n;
int dp(int i, int j)
{
    if (s[i][j]!=0)
    {
        return s[i][j];
    }

    //    m1=m2=m3=m4=-1;
    //    if(d[i-1][j]<=d[i][j])
    //        m1=dp(i-1,j)+1;
    //    if(d[i+1][j]<=d[i][j])
    //        m2=dp(i+1,j)+1;
    //    if(d[i][j-1]<=d[i][j])
    //        m3=dp(i,j-1)+1;
    //    if(d[i][j+1]<=d[i][j])
    //        m4=dp(i,j+1)+1;
    //return max(m1,max(m2,max(m3,m4)));
    int maxm = 0;
    if (d[i][j] > d[i - 1][j] && maxm < dp(i - 1, j))
        maxm = dp(i - 1, j);
    if (d[i][j] > d[i][j - 1] && maxm < dp(i, j - 1))
        maxm = dp(i, j - 1);
    if (d[i][j] > d[i + 1][j] && maxm < dp(i + 1, j))
        maxm = dp(i + 1, j);
    if (d[i][j] > d[i][j + 1] && maxm < dp(i, j + 1))
        maxm = dp(i, j + 1);
    s[i][j] = maxm + 1;
    return s[i][j];
}
int main()
{

    cin >> m >> n;
    for (int i = 1; i <= m; i++)
    {
        for (int j = 1; j <= n; j++)
        {
            cin >> d[i][j];
            if (d[i][j] > maxd)
            {
                maxd = d[i][j];
                max_r = i;
                max_c = j;
            }
            if (d[i][j] < mind)
            {
                mind = d[i][j];
                min_r = i;
                min_c = j;
            }
        }
    }
    for (int i = 0; i <= m + 1; i++)
    {
        d[i][0] = maxn;
        d[i][n + 1] = maxn;
    }
    for (int j = 0; j <= n + 1; j++)
    {
        d[0][j] = maxn;
        d[m + 1][j] = maxn;
    }
    s[min_r][min_c]=1;
    int maxnum = -1;
    for (int i = 1; i <= m; i++)
    {
        for (int j = 1; j <= n; j++)
        {
            if (dp(i, j) > maxnum)
                maxnum = dp(i, j);
        }
    }
    cout << maxnum << endl;
}

PS 今天配置vscode很久,各類報錯。blog

相關文章
相關標籤/搜索