就是求最长下降序列,就是深搜并记录矩阵中每个地方的最长降序列。
状态转移方程为: dp[ i ][ j ] = MAX( dp[ i - 1 ][ j ] , dp[ i + 1 ][ j ], dp[ i ][ j - 1], dp[ i ][ j + 1] ) + 1; 当然写代码时要注意越界判断。
代码可能有点冗长,可以用方向数组,判断条件就不会这么麻烦了。
#include <iostream>
using namespace std;
const int size = 102;
int map[size][size];
int dp[size][size];
int row, col, maxLen;
int getLenth(int r, int c)
{
if(dp[r][c] > 0) // 当某一点的长度大于0,则该处被访问过,且存储的最长降序列的长度。
return dp[r][c];
// 当某一点无法下滑时,即到达底部,长度为1
if( ((r > 0 && map[r-1][c] >= map[r][c]) || r == 0) && ((r < row-1 && map[r+1][c] >= map[r][c]) || r == row-1)
&& ((c > 0 && map[r][c-1] >= map[r][c]) || c == 0) && ((c < col-1 && map[r][c+1] >= map[r][c]) || c == col-1) )
return (dp[r][c] = 1);
int tmp;
if(r > 0 && map[r-1][c] < map[r][c]) //求出四个方向的降序列的长度,dp[r][c]存储其中最长的序列
{
tmp = getLenth(r-1, c) + 1;
if(tmp > dp[r][c])
dp[r][c] = tmp;
}
if(r < row-1 && map[r+1][c] < map[r][c])
{
tmp = getLenth(r+1, c) + 1;
if(tmp > dp[r][c])
dp[r][c] = tmp;
}
if(c > 0 && map[r][c-1] < map[r][c])
{
tmp = getLenth(r, c-1) + 1;
if(tmp > dp[r][c])
dp[r][c] = tmp;
}
if(c < col-1 && map[r][c+1] < map[r][c])
{
tmp = getLenth(r, c+1) + 1;
if(tmp > dp[r][c])
dp[r][c] = tmp;
}
if(dp[r][c] > maxLen)
maxLen = dp[r][c]; //存储得到的最长降序列长度,即题目中的答案
return dp[r][c];
}
int main()
{
int i, j;
memset(dp, 0, sizeof(dp));
maxLen = 1; // 初始化为1,因为降序列最短距离为1
scanf("%d %d", &row, &col);
for(i = 0; i < row; i++)
for(j = 0; j < col; j++)
scanf("%d", &map[i][j]);
for(i = 0; i < row; i++)
for(j = 0; j < col; j++)
getLenth(i, j);
printf("%d\n", maxLen);
//system("pause");
return 0;
}