Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include<bits/stdc++.h>
- using namespace std;
- #define sc( x ) scanf( "%d" , &x )
- #define REP( i , n ) for( int i = 0 ; i < n ; ++i )
- #define clr( t , val ) memset( t , val , sizeof( t ) )
- #define pb push_back
- #define all( v ) v.begin() , v.end()
- #define SZ( v ) ((int)(v).size())
- #define mp make_pair
- #define fi first
- #define se second
- #define N 2000
- #define M 200
- #define INF (1LL<<50)
- typedef vector< int > vi;
- typedef long long ll;
- typedef pair< int , int > pii;
- int n , m , L;
- string a , b;
- bool used[ N + 5 ][ N + 5 ];
- ll memo[ N + 5 ][ N + 5 ];
- ll C[ M + 5 ][ M + 5 ];
- ll G1[ M + 5 ][ M + 5 ];
- ll G2[ M + 5 ][ M + 5 ];
- ll I1[ M + 5 ][ M + 5 ];
- ll I2[ M + 5 ][ M + 5 ];
- ll get1( int c , int forb , ll &ind ){
- if( G1[ c ][ forb ] != -1 ){
- ind = I1[ c ][ forb ];
- return G1[ c ][ forb ];
- }
- ll mini = INF;
- REP( i , L ) if( i != forb ) {
- if( C[ c ][ i ] < mini ){
- mini = C[ c ][ i ];
- ind = i;
- }
- }
- G1[ c ][ forb ] = mini;
- I1[ c ][ forb ] = ind;
- return mini;
- }
- ll get2( int c , int forb , ll &ind ){
- if( G2[ c ][ forb ] != -1 ){
- ind = I2[ c ][ forb ];
- return G2[ c ][ forb ];
- }
- ll mini = INF;
- REP( i , L ) if( i != forb ){
- if( C[ i ][ c ] < mini ){
- mini = C[ i ][ c ];
- ind = i;
- }
- }
- G2[ c ][ forb ] = mini;
- I2[ c ][ forb ] = ind;
- return mini;
- }
- ll dp( int x , int y ){
- //cout << x << " " << y << endl;
- if( x == n && y == m ) return 0;
- if( used[ x ][ y ] ) return memo[ x ][ y ];
- used[ x ][ y ] = 1;
- ll ind;
- ll &dev = memo[ x ][ y ] = INF;
- if( y < m ) dev = min( dev , get2( b[ y ] , (x < n) ? a[ x ] : L , ind ) + dp( x , y + 1 ) );
- if( x < n ) dev = min( dev , get1( a[ x ] , (y < m) ? b[ y ] : L , ind ) + dp( x + 1 , y ) );
- if( x < n && y < m ) dev = min( dev , C[ a[ x ] ][ b[ y ] ] + dp( x + 1 , y + 1 ) );
- return dev;
- }
- vector< int > sol1 , sol2;
- void rec( int x , int y ){
- if( x == n && y == m ) return ;
- ll ind;
- if( y < m ) {
- if( dp(x , y) == get2( b[ y ] , (x < n) ? a[ x ] : L , ind ) + dp( x , y + 1 ) ){
- sol1.pb( ind );
- sol2.pb( b[ y ] );
- rec( x , y + 1 );
- return;
- }
- }
- if( x < n ){
- if( dp(x , y) == get1( a[ x ] , (y < m) ? b[ y ] : L , ind ) + dp( x + 1 , y ) ){
- sol1.pb( a[ x ] );
- sol2.pb( ind );
- rec( x + 1 , y );
- return;
- }
- }
- if( x < n && y < m ){
- if( dp( x , y ) == C[ a[ x ] ][ b[ y ] ] + dp( x + 1 , y + 1 ) ){
- sol1.pb( a[ x ] );
- sol2.pb( b[ y ] );
- rec( x + 1 , y + 1 );
- return;
- }
- }
- }
- int main(){
- /*
- freopen( "dissim.in" , "r" , stdin );
- freopen( "dissim.out" , "w" , stdout );
- */
- string alp;
- while( cin >> alp ){
- getline( cin , a );
- getline( cin , a );
- getline( cin , b );
- vector< int > mapa( 1000 );
- REP( i , SZ( alp ) ) mapa[ alp[ i ] ] = i;
- REP( i , SZ( a ) ) a[ i ] = mapa[ a[ i ] ];
- REP( i , SZ( b ) ) b[ i ] = mapa[ b[ i ] ];
- n = SZ( a );
- m = SZ( b );
- L = SZ( alp );
- REP( i , L ) REP( j , L ) cin >> C[ i ][ j ];
- clr( G1 , -1 );
- clr( G2 , -1 );
- clr( I1 , -1 );
- clr( I2 , -1 );
- clr( used , 0 );
- printf( "%I64d\n" , dp( 0 , 0 ) );
- sol1.clear() , sol2.clear();
- rec( 0 , 0 );
- REP( i , SZ( sol1 ) ) printf( "%c" , alp[ sol1[ i ] ] );
- puts( "" );
- REP( i , SZ( sol2 ) ) printf( "%c" , alp[ sol2[ i ] ] );
- puts( "" );
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment