CodeChef submission 130622 (C++ 4.0.0-8) plaintext list. Status: AC, problem J5, contest NOV09. By askvij (Ashok Vijay), 2009-11-11 10:43:51.
#include <vector> #include <map> #include <algorithm> #include <iostream> #include <cstdio> #include <ctime> #include <cstring> using namespace std; #define SZ 2002 string A = "abcdefghijklmnopqrstuvwxyz" ; bool found [ 27 ]; char in [ SZ ]; int odd ( int , int ); int even ( int , int ); int memo_odd [ SZ ][ SZ] ,memo_even [SZ][SZ], POS [ SZ ] [27], POS1 [SZ][27],cnt; int memo_odd1 [SZ][SZ] ,memo_even1 [SZ][SZ]; typedef pair < bool , int > PBI; typedef pair < PBI ,int > PBII; map < PBII ,string > MEMO; int even ( int idx1 , int idx2 ) { if ( idx1 > idx2 ) return 0; if ( memo_even[idx1][idx2] != -1 ) return memo_even [idx1][idx2]; int ret = 0, tmp = 0,i ,j,k; if ( in [ idx1 ] > in [idx2 ] ) tmp = odd( idx1 + 1, idx2 -1 ) + 2 ; if ( tmp > ret ) ret = tmp; tmp = even ( idx1+ 1, idx2 ); if ( tmp > ret ) ret = tmp; tmp = even ( idx1 , idx2-1 ) ; if ( tmp > ret ) ret = tmp; if ( ret == 0 && idx2 - idx1 >= 0 ) ret = 1; return memo_even [idx1][idx2] = ret; } int odd ( int idx1 ,int idx2 ) { if ( idx1 > idx2 ) return 0; if ( memo_odd[idx1][idx2] != -1 ) return memo_odd [idx1][idx2]; int ret = 0, tmp = 0,i ,j,k; if ( in [ idx1 ] < in [idx2 ] ) tmp = even( idx1 + 1, idx2 -1 ) + 2 ; if ( tmp > ret ) ret = tmp; tmp = odd ( idx1+ 1, idx2 ); if ( tmp > ret ) ret = tmp; tmp = odd ( idx1 , idx2-1 ) ; if ( tmp > ret ) ret = tmp; if ( ret == 0 && idx2 - idx1 >= 0 ) ret = 1; return memo_odd [idx1][idx2] = ret; } /*void print_ans ( int n ) { int i ,j, k ,idx1 = 0 , idx2 = n-1; for ( i = 0 ; i < n ;i++ ,cout <<"\n" ) for ( j = 0 ; j < n ;j++ ) cout << memo_odd [i][j] << " ";cout<<"\n\n"; for ( i = 0 ; i < n ;i++ ,cout <<"\n" ) for ( j = 0 ; j < n ;j++ ) cout << memo_even [i][j] << " ";cout<<"\n\n"; }*/ string recurse ( bool isodd , int idx1 , int idx2 ) { int i ,j,k; if ( idx1 > idx2 ) return ""; string ret = "" ,tmp ; PBII a = make_pair ( make_pair ( isodd ,idx1 ) ,idx2 ); if ( MEMO[a].size() ) return MEMO [a]; int n,m; if ( isodd ) n = memo_even1 [idx1][idx2]; else n = memo_odd1 [idx1][idx2]; if ( n == 1 ) { for ( i = 0 ; i < cnt; i++ ) if ( POS [idx2][i] > idx1 ) { return MEMO [a] = A[i]; } } for ( i = 0 ; i < cnt ;i++ ) if ( POS1[idx1][i] != -1) { int b = POS1 [idx1][i]; if ( isodd ) { int last = -1; for ( j = i+1 ; j < cnt ; j++ ) if ( POS [idx2][j] != -1 ) { k = POS [idx2][j]; if ( k <= b || last > k ) continue; last = max ( last ,k ); if ( memo_odd1 [b][k]+2 == memo_even1[idx1][idx2] ) { tmp = A [i] + recurse ( !isodd , b ,k) +A [j]; if ( ret.size() == 0 ) ret = tmp ; else ret = min ( ret ,tmp ); } } } else { int last = -1; for ( j = 0 ; j < i ;j++ ) if ( POS [idx2][j] != -1 ) { k = POS [idx2][j]; if ( k <= b || last > k ) continue; last = max ( last ,k ); if (memo_even1 [b][k]+2 == memo_odd1[idx1][idx2] ) { tmp = A [i] + recurse (!isodd,b,k ) + A [j] ; if ( ret.size() == 0 ) ret = tmp ; else ret = min ( ret ,tmp ); } } } if ( ret.size() ) return MEMO [a] = ret; } for ( i = 0 ; i < cnt; i++ ) if ( POS [idx2][i] > idx1 ) { return MEMO [a] = A[i]; } return MEMO[a] = ret; } int main () { // double start = clock(); int t; // freopen ( "J5_1.in", "r",stdin ); //freopen ( "J5_14.out", "w",stdout ); { int i ,j,k; for ( i = 0 ; i < n ;i++ ) found [ in [i] - 'a' ] = true; j = 0; for ( i = 0 ; i < 26 ;i++ ) if ( found [i] ) { A [j] = 'a' + i; j++; } for ( i = 0 ; i < j ;i++ ) found [i] = true; // cout << A <<" "<<j<<"\n"; cnt = j; for ( i = 1 ; i < n ;i++ ) { for ( j = 0 ; j < cnt ;j++ ) if ( in [i-1] == A[j] ) POS [i][j] = i-1 ; else POS [i][j] = POS [i-1][j]; } for ( i = n - 2 ; i >= 0 ;i-- ) { for ( j = 0 ; j < cnt ;j++ ) if ( in [i+1] == A[j] ) POS1 [i][j] = i+1 ; else POS1 [i][j] = POS1 [i+1][j]; } //memset ( memo_even,-1 ,sizeof (memo_even ) ); //memset ( memo_odd,-1 ,sizeof (memo_odd ) ); //int ans = odd ( 0,n-1); for( i = 0 ; i < n ;i++ ) memo_odd1 [i][i] = memo_even1 [i][i] = 1; for ( i = n - 1; i >= 0 ;i-- ) { for ( j = i + 1 ;j < n ;j++ ) { memo_odd1 [i][j] = max ( memo_odd1 [i+1][j] ,memo_odd1[i][j-1] ); memo_even1 [i][j] = max ( memo_even1 [i+1][j] ,memo_even1[i][j-1] ); if ( in [i] > in [j] ) memo_even1 [i][j] = max ( memo_even1 [i][j] , memo_odd1 [i+1][j-1]+2 ); if ( in [i] < in [j] ) memo_odd1 [i][j] = max ( memo_odd1 [i][j] , memo_even1 [i+1][j-1]+2 ); } } int ans = memo_odd1 [0][n-1]; //cout << ans << "\n"; /* for ( i = 0; i < n ;i++ ,cout <<"\n") for ( j = 0 ; j < n ;j++ ) cout << memo_odd [i][j] << " "; cout <<"\n"; for ( i = 0; i < n ;i++ ,cout <<"\n") for ( j = 0 ; j < n ;j++ ) cout << memo_odd1 [i][j] << " "; cout <<"\n"; cout << in << "\n"; for ( i = 0; i < n ;i++ ,cout <<"\n") for ( j = 0 ; j < n ;j++ ) cout << memo_even [i][j] << " "; cout <<"\n"; for ( i = 0; i < n ;i++ ,cout <<"\n") for ( j = 0 ; j < n ;j++ ) cout << memo_even1 [i][j] << " "; cout <<"\n";*/ MEMO.clear(); if ( ans == 1 ) { string ret = "z"; for ( i = 0 ; i < n ;i++ ) ret [0] = min ( ret [0] , in [i] ) ; cout << ret <<"\n"; continue; } if ( ans == 2 ) { bool flag = false; j = k = 0; for ( i = 0 ; i < cnt ;i++ ) if ( A [i] == in [0] ) j = i ; else if ( A [i ]== in [n-1] ) k = i; POS1[0][j] = 0; POS [n-1][k] = n-1; for ( i = 0 ; i < cnt && !flag;i++ ) if ( found [i] ) for ( j = i + 1 ; j < cnt && !flag;j++ ) if ( found [j] && POS[n-1][j] > POS1 [0][i]) { flag = true; } continue; } string tmp ,ANS = "" ; bool flag = false; for ( i = 0 ; i < cnt && !flag;i++ ) if ( found [i] ) for ( j = i + 1 ; j < cnt ;j++ ) if ( found [j] ) { int a = POS1[0][i] , b = POS[n-1] [j]; if ( in [0] == A[i] ) a = 0; if ( in [ n-1] == A[j] ) b = n-1; if ( memo_even1 [ a+1 ] [ b-1 ] + 2 == ans ) { tmp= A[i] + recurse ( false ,a , b ) + A[j]; if ( ANS.size() < tmp.size() ) ANS = tmp; else if ( ANS.size() == tmp.size() ) ANS = min ( ANS , tmp ); flag = true; } } cout << ANS << "\n"; //printf("%s\n",ANS.c_str() ); } //double stop = clock(); // cout << (stop - start )/CLOCKS_PER_SEC << "\n"; return 0; }
Comments

