OPJ90:滑雪(动态规划)
解法一:人人为我----动态规划
人人为我指的就是利用若干个值已知的状态的值,推算出一个值未知的状态的值。 用 L[i][j] 表示从点 (i,j) 出发的最长滑行长度,如果周围没有比它低的点,则L (i.j) =1,否则就等于其周围四个点中高度比它低且L值最大的那个点的值再加1. 先将每个点排好序,然后通过大小依次计算他们的L值,利用递推公式求得即可。
# include <bits/stdc++.h>
using namespace std;
struct node {
int r, c, h;
bool operator< ( const node& p) const {
return h< p. h;
}
} n[ 10011 ] ;
int main ( ) {
int R, C;
cin>> R>> C;
int a[ 111 ] [ 111 ] , L[ 111 ] [ 111 ] ;
for ( int i= 1 ; i<= R; i++ ) {
for ( int j= 1 ; j<= C; j++ ) {
cin>> a[ i] [ j] ;
n[ ( i- 1 ) * C+ j] . h= a[ i] [ j] ;
n[ ( i- 1 ) * C+ j] . r= i;
n[ ( i- 1 ) * C+ j] . c= j;
L[ i] [ j] = 1 ;
}
}
sort ( n+ 1 , n+ R* C+ 1 ) ;
for ( int i= 1 ; i<= R* C; i++ ) {
int r= n[ i] . r;
int c= n[ i] . c;
if ( r- 1 >= 0 && a[ r- 1 ] [ c] < a[ r] [ c] ) {
L[ r] [ c] = max ( L[ r- 1 ] [ c] + 1 , L[ r] [ c] ) ;
}
if ( c- 1 >= 0 && a[ r] [ c- 1 ] < a[ r] [ c] ) {
L[ r] [ c] = max ( L[ r] [ c- 1 ] + 1 , L[ r] [ c] ) ;
}
if ( r+ 1 <= R&& a[ r+ 1 ] [ c] < a[ r] [ c] ) {
L[ r] [ c] = max ( L[ r+ 1 ] [ c] + 1 , L[ r] [ c] ) ;
}
if ( c+ 1 <= C&& a[ r] [ c+ 1 ] < a[ r] [ c] ) {
L[ r] [ c] = max ( L[ r] [ c+ 1 ] + 1 , L[ r] [ c] ) ;
}
}
int maxL= 1 ;
for ( int i= 1 ; i<= R; i++ ) {
for ( int j= 1 ; j<= C; j++ ) {
maxL= max ( maxL, L[ i] [ j] ) ;
}
}
cout<< maxL<< endl;
return 0 ;
}
解法二:我为人人----动态规划
我为人人值得就是用本身已知的状态X (我) 会对哪些数据 (人人) 有影响导致其更新数据。 与上述不同的是,这里是找到已知状态X,然后对其周边的四个数据,如果比周边四个数据小的话,周边四个的 L 就等于递推公式: L = max(L(x)+1) , L),从而对符合条件的数据进行更新。
# include <bits/stdc++.h>
using namespace std;
struct node {
int r, c, h;
bool operator< ( const node& p) const {
return h< p. h;
}
} n[ 10011 ] ;
int main ( ) {
int R, C;
cin>> R>> C;
int a[ 111 ] [ 111 ] , L[ 111 ] [ 111 ] ;
for ( int i= 1 ; i<= R; i++ ) {
for ( int j= 1 ; j<= C; j++ ) {
cin>> a[ i] [ j] ;
n[ ( i- 1 ) * C+ j] . h= a[ i] [ j] ;
n[ ( i- 1 ) * C+ j] . r= i;
n[ ( i- 1 ) * C+ j] . c= j;
L[ i] [ j] = 1 ;
}
}
sort ( n+ 1 , n+ R* C+ 1 ) ;
for ( int i= 1 ; i<= R* C; i++ ) {
int r= n[ i] . r;
int c= n[ i] . c;
if ( r- 1 > 0 && a[ r- 1 ] [ c] > a[ r] [ c] ) {
L[ r- 1 ] [ c] = max ( L[ r] [ c] + 1 , L[ r- 1 ] [ c] ) ;
}
if ( c- 1 > 0 && a[ r] [ c- 1 ] > a[ r] [ c] ) {
L[ r] [ c- 1 ] = max ( L[ r] [ c] + 1 , L[ r] [ c- 1 ] ) ;
}
if ( r+ 1 <= R&& a[ r+ 1 ] [ c] > a[ r] [ c] ) {
L[ r+ 1 ] [ c] = max ( L[ r] [ c] + 1 , L[ r+ 1 ] [ c] ) ;
}
if ( c+ 1 <= C&& a[ r] [ c+ 1 ] > a[ r] [ c] ) {
L[ r] [ c+ 1 ] = max ( L[ r] [ c] + 1 , L[ r] [ c+ 1 ] ) ;
}
}
int maxL= 1 ;
for ( int i= 1 ; i<= R; i++ ) {
for ( int j= 1 ; j<= C; j++ ) {
maxL= max ( maxL, L[ i] [ j] ) ;
}
}
cout<< maxL<< endl;
return 0 ;
}