信息学竞赛题解(IO题解)动态规划

BZOJ-3304: [Shoi2005]带限制的最长公共子序列

2018-10-16  本文已影响2人  AmadeusChan

题目:http://www.lydsy.com/JudgeOnline/problem.php?id=3304

LCS的变种,虽然不难,但是细节挺多的,而且要滚动数组才能过。

代码:

a2cc7cd98d1001e983229e7cba0e7bec54e797a3.jpg.png
#include <cstdio>
#include <algorithm>
#include <cstring>
 
using namespace std ;
 
#define MAXN 510
 
char s0[ MAXN ] , s1[ MAXN ] , s2[ MAXN ] ;
int n , m , w , f[ 2 ][ MAXN ][ MAXN ] , h = 0 , ans = 0 ;
 
int main(  ) {
    scanf( "%s%s%s" , s0 + 1 , s1 + 1 , s2 + 1 ) ;
    n = strlen( s0 + 1 ) , m = strlen( s1 + 1 ) , w = strlen( s2 + 1 ) ;
    f[ 0 ][ 0 ][ 0 ] = 0 ; 
    for ( int i = 0 ; i ++ < n ; ) {
        for ( int j = 0 ; j ++ < m ; ) for ( int k = 0 ; k <= w ; k ++ ) {
            f[ h ^ 1 ][ j ][ k ] = max( max( f[ h ][ j ][ k ] , f[ h ^ 1 ][ j - 1 ][ k ] ) , f[ h ][ j - 1 ][ k ] );
            if ( s0[ i ] == s1[ j ] ) {
                if ( f[ h ][ j - 1 ][ k ] || k == 0 ) f[ h ^ 1 ][ j ][ k ] = max( f[ h ^ 1 ][ j ][ k ] , f[ h ][ j - 1 ][ k ] + 1 ) ;
                if ( s0[ i ] == s2[ k ] && ( f[ h ][ j - 1  ][ k - 1 ] || ( k - 1 ) == 0 ) ) {
                    f[ h ^ 1 ][ j ][ k ] = max( f[ h ^ 1 ][ j ][ k ] , f[ h ][ j - 1 ][ k - 1 ] + 1 ) ;
                }
            }
        }
        for ( int j = 0 ; j ++ < m ; ) ans = max( ans , f[ h ^ 1 ][ j ][ w ] ) ;
        h ^= 1 ;
    }
    if ( ans - 1 > 0 ) printf( "%d\n" , ans ) ; else printf( "NO SOLUTION\n" ) ;
    return 0 ;
}

上一篇下一篇

猜你喜欢

热点阅读