0w1

CFR 219 C. Color Stripe ( DP, Restoration )

Problem - 219C - Codeforces
題意:
給一個字串,求為使所有相鄰字母相異,需要修改最少次數的方法。
解法:
dp[ i ][ j ] : 使前 i 個字母合法,最後一個字母為 'A' + j,此時的最少修改數。
dp[ i ][ j ] = min{ min{ dp[ i - 1 ][ k ] | k ≠ j }, dp[ i - 1 ][ j ] + 1 }

int N, K;
string seq;

void init(){
    cin >> N >> K;
    cin >> seq;
}

vvi dp;
vvi pre;

void preprocess(){
    dp = vvi( N + 1, vi( K, INF ) );
    pre = vvi( N + 1, vi( K, -1 ) );
    for( int i = 0; i < K; ++i )
        dp[ 0 ][ i ] = 0;
    for( int i = 0; i < N; ++i )
        for( int j = 0; j < K; ++j )
            if( dp[ i ][ j ] < INF )
                for( int k = 0; k < K; ++k )
                    if( j != k )
                        if( upmin( dp[ i + 1 ][ k ], dp[ i ][ j ] + ( seq[ i ] != 'A' + k ) ) )
                            pre[ i + 1 ][ k ] = j;
}

void solve(){
    int ans = INF;
    for( int i = 0; i < K; ++i )
        upmin( ans, dp[ N ][ i ] );
    cout << ans << endl;
    for( int i = 0; i < K; ++i )
        if( ans == dp[ N ][ i ] ){
            stack< char > show;
            for( int u = i, n = N; ~pre[ n ][ u ]; u = pre[ n-- ][ u ] )
                show.push( ( char )( 'A' + u ) );
            for( ; not show.empty(); show.pop() )
                cout << show.top();
            cout << endl;
            return;
        }
}