问题:
给出一个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;
}