题目出处
思路:记忆化DFS,把每个点搜到的最大长度记录下来,这样如果在下一个点搜到以前点的话,直接加上那个点的最大长度即可,但还是要注意一些细节,比如有可能在一次搜索里多次碰到以前的点,这时候就不能无脑加长度,而是要判断哪个加了以前的长度后最大,必须每次记录最大长度
代码如下:
package search;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;
public class P1434 {
static int res, tempRes, R, C, map[][], xx[] = { 0, 0, 1, -1 }, yy[] = { 1, -1, 0, 0 }, temp[][];
// static boolean vis[][];
public static void main(String[] args) throws IOException {
BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
StreamTokenizer st = new StreamTokenizer(bf);
st.nextToken();
R = (int) st.nval;
st.nextToken();
C = (int) st.nval;
map = new int[R][C];
temp = new int[R][C];
// vis = new boolean[R][C];
for (int i = 0; i < R; ++i) {
for (int j = 0; j < C; ++j) {
st.nextToken();
map[i][j] = (int) st.nval;
}
}
for (int i = 0; i < R; ++i) {
for (int j = 0; j < C; ++j) {
tempRes = 0;//每次置0
dfs(i, j, 1);
temp[i][j] = tempRes;//temp[][]存储每次搜索的tempRes
res = Math.max(res, tempRes);//取最大的tempRes
}
}
System.out.println(res);
}
public static void dfs(int x, int y, int step) {
tempRes = Math.max(tempRes, step);//取目前为止最大的step并存储为tempRes
//特殊情况如下(这就是记忆化搜索):
if (temp[x][y] != 0) {//如果当前这个点以前搜过,那么就只要加上这个点的tempRes即可,然后再和这次搜索里目前为止最大的tempRes比较取最大
tempRes = Math.max(tempRes, step - 1 + temp[x][y]);
return;//既然这个点以前搜过就没有必要以这个点为基础往下找了,直接返回
}
for (int i = 0; i < 4; ++i) {
int row = x + xx[i];
int col = y + yy[i];
if (row >= 0 && row < R && col >= 0 && col < C && map[row][col] < map[x][y]) {
dfs(row, col, step + 1);
}
}
}
}