dfs+回溯
对于点[i,j],其最长路径由上下左右四个点决定。递归求解周围四点即可。由于路径严格递减,故不用担心无限循环的情况。

#include<iostream>

using namespace std;
const int MAXN = 105;
int n, m;
int map[MAXN][MAXN];
int dplen[MAXN][MAXN];

int dfs(int i, int j, int pre){
    if(i < 0 || i == n || j < 0 || j == m)//边界情况
        return 0;
    if(pre <= map[i][j])    //严格递减
        return 0;
    if(dplen[i][j] != 0)    //保证只访问一次map[i][j],故时间复杂度为O(nm)
        return dplen[i][j];
    int cur = 0;    //若此点为低谷,即四周都没有路,那么长度为0
    cur = max(cur, dfs(i-1, j, map[i][j]));
    cur = max(cur, dfs(i+1, j, map[i][j]));
    cur = max(cur, dfs(i, j-1, map[i][j]));
    cur = max(cur, dfs(i, j+1, map[i][j]));
    dplen[i][j] = cur + 1;        //路径+1,保证取得最长的路径
    return dplen[i][j];
}

int main(){
    scanf("%d %d", &n, &m);
    for(int i = 0; i < n; ++i)
        for(int j = 0; j < m; ++j)
            scanf("%d", &map[i][j]);
    
    int mmax = 1;
    for(int i = 0; i < n; ++i)
        for(int j = 0; j < m; ++j)    //遍历,并求最长路径长度
            mmax = max(mmax, dfs(i, j, 1005));  //最大高度不超过1000
    cout << mmax;
    
    return 0;
}