POJ 1088 滑雪 (记忆化搜索 DFS) java

                                               POJ 滑雪 题目链接
 


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
 


文章大意:  给定一个N行M列的数字矩阵,问其中最长的下降路径。 (N,M<=100)

题解: 我们可以用 DFS 遍历坐标 搜索上下左右四个方向  再给每个点找出最长距离之后用 一个标记数组保存结果 ,等下次遇到这个坐标的时候 , 直接将值加上走过的距离,来避免重复的搜索 



import java.util.Scanner;

public class Main {
	static int n = 0;
	static int n1 = 0;
	static int max = 0; // 存放当前这跳路的最大值
	static int arr[][]; // 滑雪数组
	static int ji[][]; // 标记数组
	static int zou1[] = { 1, -1, 0, 0 }; // 移动
	static int zou2[] = { 0, 0, 1, -1 };
	static int max2 = 0; // 输出结果 全局路的最大指

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner sc = new Scanner(System.in);
		while (sc.hasNext()) {
			max2 = 0;
			n = sc.nextInt(); // 数组的长和宽
			n1 = sc.nextInt();
			arr = new int[n][n1];
			ji = new int[n][n1];
			for (int i = 0; i < arr.length; i++) { // 初始化
				for (int k = 0; k < arr[i].length; k++) {
					arr[i][k] = sc.nextInt();
					ji[i][k] = -1;
				}
			}
			for (int i = 0; i < arr.length; i++) {
				for (int k = 0; k < arr[i].length; k++) {
					max = 0;
					sou(i, k, 1); //找出i k 这个点的最大距离 赋值给 max
			
					ji[i][k] = max; //将 max 记录在标记数组中
					
					if (max > max2) { //筛选最大的标记数组
						max2 = max;
					}

					max = 0;
				}

			}

			System.out.println(max2);

		}
	}

	static void sou(int i, int j, int sum) { // 通过这个方法每回合 可以找出 i j坐标的开始滑雪的最大值

		if (sum >= max) {
			max = sum;
		}
		for (int q = 0; q < 4; q++) {
			int x1 = i + zou1[q]; //移动
			int y1 = j + zou2[q];
			if ((x1 >= 0 && x1 < n) && (y1 >= 0 && y1 < n1) && (arr[i][j] > arr[x1][y1])) {
				if (ji[x1][y1] == -1) {//如果这个位置没有走过 那就接着搜
					sou(x1, y1, sum + 1);
				} else { // 如果这个地方走过了 那就直接获取 这个位置的最大距离与之前走过的和
					int aq = sum;
					sum = sum + ji[x1][y1];
					if (sum >= max) {
						max = sum;
					}
					sum = aq; //之前的操作改变了sum 所以这个步骤是为了返还 sum数值

				}
			}

		}

	}

}

 

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值