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);
    }
}

  

 

posted @ 2020-07-22 19:41  吐司奶猫荷包蛋  阅读(114)  评论(0)    收藏  举报