這是一個動態規劃問題(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;
}
}