Problem
顺治喜欢滑雪,这并不奇怪, 因为滑雪的确很刺激。可是为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待太监们来载你。顺治想知道载一个区域中最长的滑坡。
区域由一个二维数组给出。数组的每个数字代表点的高度。下面是一个例子:
1 2 3 4 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
|
顺治可以从某个点滑向上下左右相邻四个点之一,当且仅当高度减小。在上面的例子中,一条可滑行的滑坡为24-17-16-1。当然25-24-23-…-3-2-1更长。事实上,这是最长的一条。
输入的第一行表示区域的行数 R 和列数 C (1≤R,C≤500) 。下面是 R 行,每行有 C 个整数,代表高度 h,0≤h<103 。
Output
输出最长区域的长度。
EX
1 2 3 4 5 6
| 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
|
思路
很典型的深搜题,rc并不算大,O(n3)不会爆,所以直接dfs每个点的最长序列。注意要记忆化每个点的长度(在dfs内记忆化效果更优,因为能保存下更多点的mem值)。
Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
| #include<iostream> #include<cstdio> using namespace std;
int ans = 0; int r,c; int height[502][502]; int mem[502][502] = {0}; int changex[4] = {-1, 1, 0, 0}; int changey[4] = {0, 0, -1, 1};
int dfs(int x, int y){ if(mem[x][y]){ return mem[x][y]; } int maxx = 0; for(int i = 0;i < 4;i++){ int xx = x + changex[i]; int yy = y + changey[i]; int hh = 0; if(height[xx][yy] < height[x][y]){ hh = dfs(xx,yy); } hh++; if(hh > maxx){ maxx = hh; } } mem[x][y] = maxx; return maxx; }
int main(){ cin>>r>>c; for(int i = 0;i <= r + 1;i++){ for(int j = 0;j <= c + 1;j++){ height[i][j] = 0x3f3f3f3f; mem[i][j] = 0; } } for(int i = 1;i <= r;i++){ for(int j = 1;j <= c;j++){ cin>>height[i][j]; } } for(int i = 1;i <= r;i++){ for(int j = 1;j <= c;j++){ int h = dfs(i,j); if(h > ans){ ans = h; } } } cout<<ans<<endl; return 0; }
|