SHOI2002滑雪

点击打开链接

直截了当:(今天做洛谷月赛有点累,不多解释了。。。)

#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;
}

猜你喜欢

转载自blog.csdn.net/palace_/article/details/80377978