因为这题中只会向高度更低的位置滑,因此不会存在一个点被多次计算的情况,因此可以用记忆化搜索
状态表示:
f[i][j]表示从(i,j)开始的最长距离
集合划分:
因为有四个方向,所有分成四类,取max即可
C++ 代码
#include <iostream>
#include <cstring>
using namespace std;
const int N = 310;
int g[N][N];
int n , m;
int f[N][N];
int dx[4] = {-1 , 0 , 1 , 0} , dy[4] = {0 , 1 , 0 , -1};
int dp(int x , int y)
{
int &v = f[x][y];
if(~v) return v;//如果被计算过,直接返回
v = 1;//每个点初始都是1
for(int i = 0 ; i < 4 ; i++)
{
int a = x + dx[i] , b = y + dy[i];
if(a >= 1 && a <= n && b >= 1 && b <= m && g[a][b] < g[x][y])
v = max(v , dp(a , b) + 1);
}
return v;
}
int main()
{
cin >> n >> m;
memset(f , -1 , sizeof f);
for(int i = 1 ; i <= n ; i++)
for(int j = 1 ; j <= m ; j++)
cin >> g[i][j];
int res = 0;
for(int i = 1 ; i <= n ; i++)
for(int j = 1 ; j <= n ; j++)
res = max(res , dp(i , j));
cout << res << endl;
return 0;
}