题目要求:
这么大的空间限制应该和深度优先搜索(暴力搜索(doge))沾边
题目中的例子应该是这个意思
从山顶滑下来路线最长的路是25
某一天,hyw去滑雪,问我最长的、最爽的一条路怎么滑?
下面,按照顺序思考
1. 首先,是不是从最高的点开始滑下来的。
显然不一定,比如这么一种地形:
1、2、3、4、5、6、7之间等距离
是红色的路线长度最长(这个题目考虑的是垂直距离,1到2的距离等于4到5的距离)
这就复杂了,得每一个点都深搜一遍,记录下最大的路线长度。
那为何不直接,每个点作为起点暴力搜索一下,总能找到答案的。
可惜会runtime error ,然后你就会和这个表情包一样
2.准备工作:
我这题的解题规范是左上角的点坐标为(1,1),右下角的为(R,C)!!!!!!
(数组的第一个元素的下标是0)
既然要遍历所有的点,那么:
先确定一个点比如24这个点
要动,就有四个方向:上下左右,hyw只有四种走法,上下左右,如果往上走,那么它的坐标变成了(x-1,y),往左变成(x,y-1),右(x,y+1),下(x+1,y),所以可以定义方向数组如下:
然后呢,有两种情况也是不符合实际的:
1、不能低处往高处滑
2、不能出界
关键点来了:
递归!
不过首先要先定义一个数组,它的作用是:
1、等于0说明这个点没有来过,不等于0说明这个点来过(走过的点不能再走)
2、假如maxlen[x][y]==5,说明点(x,y)接下来最长的路是5
什么意思?这个地方需要倒过来想,最后一个点的maxLen是1,倒数第二个是2,以此类推
接下来模拟一下,假如你到了一个新的点:
判断maxLen是不是0
(1)不是0的话说明走过了,并且返回这个点的maxLen值,表示接下去的最长路径
(2)是0,先标记一下1,说明到此一游,然后往四个方向各试一遍,比较是四个方向的其中一个点+1最长,还是我这个点接下去的最长路径长(现在不懂没关系,看完下面的具体例子再回来看应该懂了)
把这个过程包装成方法dfs(dfs——deepth first search深度优先搜索)对每个点用一次,找出最大值
具体例子:
5*5的矩阵: ----此时的maxLen[][]:
开始遍历:
初始值dis==1
点[1][1]由于周围要么是1要么越界所以dfs一次之后变为:
矩阵:------------- 此时的maxLen[][]:
这种情况会一直持续到[3][2]:
矩阵:------------- 此时的maxLen[][]:
然后开始[3][3]:
矩阵:------------- 此时的maxLen[][]:
根据这个步骤
maxLen[3][3]是0,令maxLen[3][3]=1;
矩阵:------------- 此时的maxLen[][]:
开始上下左右走:
(1)向上
没有出界并且高度是向下的,到这一步
变为maxLen[3][3] = max(dfs(2,3) + 1, 1)
而dfs(2,3) 为多少呢?
按照这个步骤:
可知,直接返回maxLen[2][3],为1;
所以maxLen[3][3] = max(2,1);为2
2是什么意思呢?
是[3][3]->[2][3]这条路径的长度!
这里是不是就清晰一点了
ok,向上完成了,最长的只有一条路径长度为2的。
矩阵:------------- 此时的maxLen[][]:
(2)向右
右边是0,说明没走过令它等于1
矩阵:------------- 此时的maxLen[][]:
然后计算一下dfs(3,4):
也是分四个方向,这里就简略写了:
向上1,向右2,向下1,向左1
矩阵:------------- 此时的maxLen[][]:
这时候
dfs(3,3 )= max(dfs(3,4)+1,maxLen[3][3])
=max(3,2)=3
就变为:
矩阵:------------- 此时的maxLen[][]:
ok,向右完成了
(3)向下
矩阵:------------- 此时的maxLen[][]:
(4)向左
矩阵:------------- 此时的maxLen[][]:
接下来就继续遍历,结束的样子就是:
矩阵:------------- 此时的maxLen[][]:
这里只是巧合!左右两张图一样,把[3][3]的点高度变为999右边maxLen图也是这么画!
找出最大值
这个函数就是每遍历一个点,有一个dfs出来的值比现在的dis大就换dis。
最后,源码:
#include<iostream>
using namespace std;
int to[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
int R, C, high[100][100], maxLen[100][100];
int dfs(int x, int y) {
if (maxLen[x][y] != 0)
return maxLen[x][y];
maxLen[x][y] = 1;
for(int i = 0; i <= 4; i++) {
int x1 = x + to[i][0];
int y1 = y + to[i][1];
//不出界并且是往低处走
if( x1 >= 1 && y1 >= 1 && x1 <= R && y1 <= C && high[x1][y1] < high[x][y]) {
maxLen[x][y] = max(dfs(x1, y1) + 1, maxLen[x][y]);
}
}
return maxLen[x][y];
}
int main() {
cin >> R >> C;
int dis = 1;
for(int i = 1; i <= R; i++) {
for(int j = 1; j <= C; j++) {
cin >> high[i][j];
maxLen[i][j] = 0;
}
}
for(int i = 1; i <= R; i++) {
for(int j = 1; j <= C; j++) {
dis = max(dis, dfs(i, j));
}
}
cout << dis << endl;
return 0;
}
完结