问题:
给出一个R行C列的二维数组表, 求出这个表中的最长递增序列的长度,只能上下左右相邻。
Sample Input
5 5 1 2 3 4 5 16 17 18 19 6 15 24 25 20 7 14 23 22 21 8 13 12 11 10 9
Sample Output
25
错误:
一开始直接普通的深搜,每一个点都深搜一遍,找出最大的。不出意料是超时的。
正解:
记忆化搜索,依然是深搜,但是用一个数组 来记录已经搜索过的点 且以这个点为起点的 最长递增序列 的长度,
这样下一次搜索到这个点的时候就直接返回长度就行,避免了重复的搜索。。。
#include <iostream> #include <algorithm> #include <cstring> #include <cmath> using namespace std; const int MAXN = 105; int R,C; int M[MAXN][MAXN]; int mark_len[MAXN][MAXN]; void init(); void get_map(int R, int C); int DFS(int x, int y); int main() { int max_len = 0; cin >> R >> C; init(); get_map(R, C); for(int i = 0;i < R;i++) { for (int j = 0; j < C; j++) { max_len = max(max_len,DFS(i,j)); } } cout << max_len << endl; system("pause"); return 0; } void init() { memset(M, 0, sizeof(M)); memset(mark_len,0,sizeof(mark_len)); } void get_map(int R, int C) { for(int i = 0;i < R;i++) { for (int j = 0; j < C;j ++) { cin >> M[i][j]; } } } int DFS(int x, int y) { // 记忆化搜索 if(mark_len[x][y] != 0) return mark_len[x][y]; int len = 1; int next[4][2] = {{0, 1},{1, 0},{0,-1},{-1,0}}; // 方向数组 for (int i = 0; i < 4; i++) { int nx = x + next[i][0]; int ny = y + next[i][1]; if(nx < 0 || ny < 0 || nx == R || ny == C) continue; else if(M[nx][ny] > M[x][y]) { // 这里想了好久才想明白,但是只能意会啊 len = max(len, DFS(nx,ny)+1); } } // 记忆化搜索 mark_len[x][y] = len; return len; }