直截了当:(今天做洛谷月赛有点累,不多解释了。。。)
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #define fill( a ) memset( a, -1, sizeof( a ) ) #define loop( i, a, b ) for( int i = a; i < b; i++ ) using namespace std; const int INF = 0x3f3f3f3f; int read() { //读入优化 char ch; bool f = false; while( ( ch = getchar() ) < '0'|| ch > '9' ) if( ch == '-' ) f = true; int res = ch-48; while( ( ch = getchar() ) >= '0' && ch <= '9' ) res = res * 10 + ch - 48; return f ? res + 1 : res; } void print( int x ) { //输出优化 if( x < 0 ) { putchar( '-' ); x = -x; } if( x > 9 ) print( x / 10 ); putchar( x % 10 + '0' ); } int ans, n, m; int a[2002][2002], f[2002][2002]; int search( int x, int y, int h ) { //记忆化搜索 ,当前坐标为( x, y ),高度为 h if( h <= a[x][y] ) return 0; //当前高度比搜到的这个位置矮,那就不能滑到搜到的位置 if( x < 0 || y < 0 || x > n - 1 || y > m - 1 ) return 0; //越界 if( f[x][y] > 0 ) return f[x][y]; //剪枝,不加TLE一个点,因为这个点总共被搜了两次及以上,这样可以只搜一次 //得到到达( x, y )这个点的最长路线长度 f[x][y] = max( max( search( x + 1, y, a[x][y] ), search( x - 1, y, a[x][y] ) ), max( search( x, y + 1, a[x][y] ), search( x, y - 1, a[x][y]) ) ) + 1; return f[x][y]; } int main() { n = read(); m = read(); loop( i, 0, n ) loop( j, 0, m ) a[i][j] = read(); fill( f ); loop( i, 0, n ) loop( j, 0, m ) { int maxn = search( i, j, INF ); ans = max( ans, maxn ); } print( ans ); return 0; }