POJ 1088 Java:滑雪(动态规划)

   这是一个动态规划问题(Dynamic programming):讲一个较大的问题分为若干的相互有关的子问题,即重叠子问题,使用递归的方法来求解。

对于这个问题来说,点A的步数为,与其相邻的四个点中高度低于A的点中,步数最长的点+1。

在计算每一个点的步数时,有些点的步数信息有可能会被重复使用,因此我们可以将每个点的步数信息计算出后存储,当再次需要时即可不必计算,直接调用。这就是记忆化搜索。


AC代码:

//滑雪,动态规划
package poj.regue;
import java.util.*;
public class Poj1088 {
	private static int height[][], memory[][];
	private static int n, m;// 记录输入数量

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		n = sc.nextInt();
		m = sc.nextInt();
		int max = 0;
		height = new int[n + 3][m + 3];
		memory = new int[n + 3][m + 3]; // 避免递归查找时数组越界
		for (int i = 1; i <= n; i++) {
			for (int j = 1; j <= m; j++) {
				if (sc.hasNext()) {
					height[i][j] = sc.nextInt();
				}
			}
		}
		
		for(int i=1; i<=n; i++){
			for(int j=1; j<=m; j++){
				memory[i][j] = dp(i, j);
				if(max < memory[i][j]){
					max = memory[i][j];
				}
			}
		}
		
		System.out.println(max);
		sc.close();
	}

	public static int dp(int x, int y) {
		int max = 0;
		int tmp;
		if (x < 1 || y < 1 || x > n || y > m) {
			// 已经到达边界
			return 0;
		}
		if (memory[x][y] != 0) {
			// 已经查找过
			return memory[x][y];
		}

		if (height[x][y] > height[x][y + 1]) {
			// 向上查找
			tmp = dp(x, y + 1);
			if (max < tmp)
				max = tmp;
		}
		if (height[x][y] > height[x][y - 1]) {
			// 向下查找
			tmp = dp(x, y - 1);
			if (max < tmp)
				max = tmp;
		}
		if (height[x][y] > height[x - 1][y]) {
			// 向左查找
			tmp = dp(x - 1, y);
			if (max < tmp)
				max = tmp;
		}
		if (height[x][y] > height[x + 1][y]) {
			// 向右查找
			tmp = dp(x + 1, y);
			if (max < tmp)
				max = tmp;
		}
		
		return max + 1;
	}

}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章