题目信息:
Michael喜欢滑雪百这并不奇怪, 因为滑雪的确很刺激。可是为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待升降机来载你。Michael想知道载一个区域中最长底滑坡。区域由一个二维数组给出。数组的每个数字代表点的高度。下面是一个例子
一个人可以从某个点滑向上下左右相邻四个点之一,当且仅当高度减小。在上面的例子中,一条可滑行的滑坡为24-17-16-1。当然25-24-23-...-3-2-1更长。事实上,这是最长的一条。
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
一个人可以从某个点滑向上下左右相邻四个点之一,当且仅当高度减小。在上面的例子中,一条可滑行的滑坡为24-17-16-1。当然25-24-23-...-3-2-1更长。事实上,这是最长的一条。
Input
输入的第一行表示区域的行数R和列数C(1 <= R,C <= 100)。下面是R行,每行有C个整数,代表高度h,0<=h<=10000。
Output
输出最长区域的长度。
Sample Input
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
Sample Output
25
分析:经典的记忆化搜索的题,注意边界的初始化问题,然后直接套模板就可以了。
用dp[i][j]表示从点(i,j)开始的所能经过的最长路径,然后每次更新最大值即可
import java.util.*;
public class Main {
static Scanner in = new Scanner(System.in);
static int ans,n,m;
static int[][]dp = new int[105][105];
static int[][] mp = new int[105][105];
static int[][] dir = {{0,1},{1,0},{0,-1},{-1,0}};
static int dfs(int x,int y) {
if(dp[x][y]>0)//搜索过了直接返回值,剪枝
return dp[x][y];
int t = 0;
for(int i = 0;i < 4;i++) {
int tx = x + dir[i][0];
int ty = y + dir[i][1];
if(tx<0||ty<0||tx>=n||ty>=m)
continue;
if(mp[tx][ty]<mp[x][y]) {//四个方向里面取最大值
t = Math.max(dfs(tx,ty) + 1,t);
}
}
return dp[x][y] = t ;
}
public static void main(String[] args) {
n= in.nextInt();
m = in.nextInt();
int i,j;
for(i = 0;i < 55;i++)
for(j = 0;j < 55;j++)
dp[i][j] = 0;
for(i = 0;i < n;i++)
for(j = 0;j < m;j++) {
mp[i][j] = in.nextInt();
}
ans = 0;
for(i = 0;i < n;i++)
for(j = 0;j < m;j++) {
//System.out.println(i+","+j+","+dp[i][j]);
ans = Math.max(dfs(i,j),ans);
}
System.out.println(ans+1);
}
}