这是一个动态规划问题(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;
}
}