滑雪--记忆化搜索

题目信息:
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);			
	}
}

猜你喜欢

转载自blog.csdn.net/JingleLiA/article/details/79680714