LIS:Longest Increasing Subsequence
int ans = 0 ;
for ( int i= 0 ; i< N; i++ ) {
dp[ i] = 1 ;
for ( int j= 0 ; j< i; j++ )
if ( A[ i] > A[ j] )
dp[ i] = max ( dp[ i] , dp[ j] + 1 ) ;
ans = max ( ans , dp[ i] ) ;
}
memset ( dp , INF , sizeof ( dp) ) ;
for ( int i= 0 ; i< N; i++ )
* lower_bound ( dp , dp+ N , A[ i] ) = A[ i] ;
cout<< lower_bound ( dp , dp+ N , INF) - dp<< endl;
LCS:Longest Common Subsequence
memset ( dp , 0 , sizeof ( dp) )
for ( int i= 0 ; i< l. length ( ) ; i++ )
for ( int j= 0 ; j< r. length ( ) ; j++ )
if ( l[ i] == r[ j] )
dp[ i+ 1 ] [ j+ 1 ] = dp[ i] [ j] + 1 ;
else
dp[ i+ 1 ] [ j+ 1 ] = max ( dp[ i+ 1 ] [ j] , dp[ i] [ j+ 1 ] ) ;
cout<< dp[ l. length ( ) ] [ r. length ( ) ] << endl;
滚动数组dp:注意为什么需要留下两维:必须先写矩形,再根据矩形优化到滚动数组
memset ( dp , 0 , sizeof ( dp) ) ;
int t = 0 ;
for ( int i= 0 ; i< l. length ( ) ; i++ ) {
t = 1 - t;
for ( int j= 0 ; j< r. length ( ) ; j++ )
if ( l[ i] == r[ j] )
dp[ t] [ j+ 1 ] = dp[ 1 - t] [ j] + 1 ;
else
dp[ t] [ j+ 1 ] = max ( dp[ t] [ j] , dp[ 1 - t] [ j+ 1 ] ) ;
}
cout<< dp[ l. length ( ) % 2 ] [ r. length ( ) ] << endl;
NlgN:记录位置,再NlgN做LIS,但是在重复元素较多时,一般并不能真正起到效果
int cnt = 0 ;
for ( int i= 0 ; i< l. length ( ) ; i++ )
for ( int j= r. length ( ) ; j>= 0 ; j-- )
if ( l[ i] == r[ j] )
F[ ++ cnt] = j;
memset ( dp , INF , sizeof ( dp) ) ;
for ( int i= 1 ; i<= cnt; i++ )
* lower_bound ( dp , dp+ cnt , F[ i] ) = F[ i] ;
cout<< lower_bound ( dp , dp+ cnt , INF) - dp<< endl;