P1434 [SHOI2002]滑雪

CSY�發表於2020-12-10

P1434 [SHOI2002]滑雪

題目描述

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

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 更長。事實上,這是最長的一條。

輸入格式

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

輸出格式

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

輸入輸出樣例

輸入 #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 1001≤R,C≤100。

考點:記憶化+dfs

記憶化也就是將某點dfs的結果記錄下來,方便下一次dfs時,不必回溯到頭;

此題非常好理解dfs,就是不撞南牆不回頭,一定要一路從高到低走到頭;

#include<bits/stdc++.h>
using namespace std;
int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0};//二維陣列dfs常用改變座標用
int n,m,ans;
int a[201][201],s[201][201];
int dfs(int x,int y)
{
	if(s[x][y])return s[x][y];//記憶化搜尋 
	s[x][y]=1;
	for(int i=0;i<4;i++)
	{
		int xx=dx[i]+x;
		int yy=dy[i]+y;// 用於遍歷四個方向 
		if(xx>0&&yy>0&&xx<=n&&yy<=m&&a[x][y]>a[xx][yy]){
			dfs(xx,yy);
			s[x][y]=max(s[x][y],s[xx][yy]+1);//記憶化 
		}
	}
	return s[x][y];
}
int main()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
		cin>>a[i][j];
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
		ans=max(ans,dfs(i,j));//取最大值 
	cout<<ans<<endl;
	return 0;
			
}