(1)f[i][j]表示以(i,j)为起点的任意方案中的最长路;
(2)将其拆分为下一步走上下左右四个方向;
(3)由于是按第一步进行分类而不是最后一步,考虑递归求dp(i,j),用f[i][j]存储答案,如果已经求出来,直接返回即可;反之f[i][j]先初始化为1,四个方向逐一尝试,如果在范围内,且下一步高度小于(i,j);那么就更新res,dp(ei,ej) + 1进行更新,即下一步最远距离 +1;得到res后返回即可。
(4)注意f先初始化为-1方便判断是否求出答案。
#include
using namespace std;
int dx[] = {0,0,1,-1},dy[] = {1,-1,0,0};
const int N = 310;
int f[N][N],h[N][N];
int n,m;
int dp(int x,int y)
{
if(f[x][y] != -1) return f[x][y];
f[x][y] = 1;
for(int i = 0;i < 4;i ++)
{
int ex = dx[i] + x,ey = dy[i] + y;
if(ex >= 1 && ex <= n && ey >= 1 && ey <= m && h[x][y] > h[ex][ey])
f[x][y] = max(f[x][y],dp(ex,ey) + 1);
}
return f[x][y];
}
int main()
{
cin >> n >> m;
for(int i = 1;i <= n;i ++)
for(int j = 1;j <= m;j ++)
cin >> h[i][j];
memset(f,-1,sizeof f);
int res = 0;
for(int i = 1;i <= n;i ++)
for(int j = 1;j <= m;j ++)
res = max(res,dp(i,j));
cout << res << endl;
return 0;
}