POJ 1088--滑雪
题目链接:http://poj.org/problem?id=1088
题目描述:
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更长。事实上,这是最长的一条。
输入:
输入的第一行表示区域的行数R和列数C(1 <= R,C <= 100)。下面是R行,每行有C个整数,代表高度h,0<=h<=10000。
输出:
输出最长区域的长度。
题解:
本题可以使用记忆化搜索,设置一个step[x][y]
1.step[x][y]表示从(x,y)开始向下滑的时候最长的步数。
2.step[x][y]表示相应的位置是否被访问过,等于初始值0则为未访问,就对step[x][y]进行搜索;
大于0就是搜索过了,且数值本身就是向下滑的最长步数,就不用继续搜索了。
递归搜索的时候 step[x][y]=max{step[x+1][y],step[x-1][y],step[x][y+1],step[x][y-1]}+1;(注意是往低处滑,看上下左右是否满足)
代码:
import java.util.Scanner;
public class Main {
static int r,c;
static int mp[][] = new int[102][102];
static int step[][] = new int[102][102];
public static int f(int x,int y) {//返回节点x,y的最长路径
if(step[x][y]!=0) {
return step[x][y]; //直接返回,不用继续搜索了
}
int rt = 0;
//向四个方向搜索
if(y<c && mp[x][y]>mp[x][y+1])
rt = Math.max(rt, f(x,y+1));
if(x<r && mp[x][y]>mp[x+1][y])
rt = Math.max(rt, f(x+1,y));
if(y>1 && mp[x][y]>mp[x][y-1])
rt = Math.max(rt, f(x,y-1));
if(x>1 && mp[x][y]>mp[x-1][y])
rt = Math.max(rt, f(x-1,y));
return step[x][y] = rt+1;
}
public static void main(String[] args) {
Scanner cin = new Scanner(System.in);
r = cin.nextInt();
c = cin.nextInt();
for(int i=1;i<=r;i++)
for(int j=1;j<=c;j++)
mp[i][j] = cin.nextInt();
int ans = 0;
for(int i=1;i<=r;i++) {
for(int j=1;j<=c;j++) {
if(step[i][j]==0) {
ans = Math.max(ans, f(i,j));
}
}
}
System.out.println(ans);
}
}

浙公网安备 33010602011771号