动态规划|AcWing 901. 滑雪
·
考察知识点:记忆化搜索、递归
这是一道模板题,或者说是例题,想要通过这一道题完全掌握该题要考察的知识点是不可能的。
对于只学过一点算法的入门者而言,想要通过自己写出题解中的递归难度是非常大的。
因此对于该题目,首先是理解怎么一回事,然后去体会记忆化递归的妙处,然后再去多做相似、相关类型的题目,对递归、计划化搜索熟悉后再回来看这道题,常看常新。
解题思路:遍历每一个点作为起点时所能滑动的距离,从中挑选出最长距离为答案。
使用二维数组记录,从某个点出发时的最长距离,这样当想要得知点(i,j)最长距离时,只要比较点(i,j)上下左右四个点哪个点最大即可。
题目中给出的束条件是实现记忆化搜索的基础,这些约束条件有:
1.只能从高处向低处滑行,这个条件保证了从f(i,j)递归时不会重复走到f(i,j)。
代码如下:
import java.util.*;
/**
* @desc 使用acwing(oj)用的模板
*/
public class Main {
//定义容器、常数、读入
int N = 310;
int[][] f = new int[N][N];
int[][] h;//heigth,存储高度的二维数组
int r,c;
int[] dx = new int[]{-1,1,0,0};
int[] dy = new int[]{0,0,-1,1};
Scanner jin = new Scanner(System.in);
//oj要用的main方法
public static void main(String[] args) {new Main().run();}//在oj中调用题解方法
void run() {
//读入题目数据
r = jin.nextInt();
c = jin.nextInt();
h = new int[r+1][c+1];
for(int i = 1; i <= r; i++){
for(int j = 1; j <= c; j++){
h[i][j] = jin.nextInt();
}
}
for(int i = 0; i < N; i++){
for(int j =0; j < N; j++){
f[i][j] = -1;
}
}
//调用解题方法
int res = -1;
for(int i = 1; i <= r; i++){
for(int j =1; j <= c; j++){
res = Math.max(res, dp(i,j));
}
}
//输出题解答案
System.out.println(res);
}
//如果成环,则无法实现该算法
int dp(int i, int j) {//从点i,j开始滑行,寻找该点作为起点的最大值
if(f[i][j] != -1) return f[i][j];
f[i][j] = 1;//没地儿可以去,就自己这个地方滑下去
for(int d = 0; d < 4; d++){//上下左右,四种方向滑一下
int a = i + dx[d],b = j + dy[d];
//边界,即不会滑出数组范围,也不会从低往高滑
if(a>=1 && a <=r && b >=1 && b <= c && h[i][j] > h[a][b]){//如果进不去,说明到头了,该返回这条路径了
f[i][j] = Math.max(f[i][j], dp(a,b)+1);
}
}
return f[i][j];//记忆化搜索
}
}
更多推荐



所有评论(0)