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

}


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