POI 17th/2010 cho/Hamsters
本题我只过了80分,但是是正解,还有两个点无法过
方法是
1、先预处理处每两个字符串接在一起要增加多少个字符
2、利用快速幂算出总共的长度
下面给出代码
1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <cmath> 5 #include <ctime> 6 #include <iostream> 7 #include <algorithm> 8 #include <stack> 9 #include <deque> 10 #include <queue> 11 #include <map> 12 #define max( x , y ) ( ( x ) > ( y ) ? ( x ) : ( y ) ) 13 #define min( x , y ) ( ( x ) < ( y ) ? ( x ) : ( y ) ) 14 #define FOR( TMP , ST , ED ) for ( int TMP = ( ST ) ; TMP < ( ED ) ; TMP ++ ) 15 #define RORD( TMP , ST , ED ) for ( int TMP = ( ST ) ; TMP > ( ED ) ; TMP ++ ) 16 const int max_int = ( 2147483467 ) ; 17 using namespace std ; 18 19 const int max_Len = 100010 , maxn = 210 ; 20 const long long oo = 1e17 ; 21 int n , m ; 22 int Len[ maxn ] ; 23 char Data[ maxn ][ max_Len ] ; 24 25 struct Node 26 { 27 long long F[ maxn ][ maxn ] ; 28 inline void operator *=( const Node &Tmp ) // next state 29 { 30 long long t[ maxn ][ maxn ] ; 31 FOR ( i , 0 , n + 1 ) 32 FOR ( j , 0 , n + 1 ) 33 { 34 long long w = oo ; 35 FOR ( k , 0 , n + 1 ) 36 w = min( w , F[ i ][ k ] + Tmp.F[ k ][ j ] ) ; 37 t[ i ][ j ] = w ; 38 } 39 // memcpy( F , t , sizeof( t ) ) ; 40 FOR ( i , 0 , n + 1 ) 41 FOR ( j , 0 , n + 1 ) 42 F[ i ][ j ] = t[ i ][ j ] ; 43 return ; 44 } 45 } Dis , Cal ; 46 47 inline void Get_Dis() // Get KMP 48 { 49 FOR ( i , 0 , n ) 50 { 51 FOR ( k , 0 , n ) 52 { 53 int now = 0 ; 54 FOR ( j , 1 , Len[ k ] ) 55 { 56 int x = 0 ; 57 while ( j + x < Len[ k ] && Data[ i ][ x ] == Data[ k ][ j + x ] ) x ++ ; 58 if ( j + x == Len[ k ] ) 59 { 60 now = x ; 61 break ; 62 } 63 } 64 Dis.F[ k ][ i ] = Len[ i ] - now ; 65 } 66 Dis.F[ n ][ i ] = Len[ i ] , Dis.F[ i ][ n ] = oo ; 67 } 68 Dis.F[ n ][ n ] = oo ; 69 return ; 70 } 71 72 int main() 73 { 74 //freopen( "hamsters.in" , "r" , stdin ) , freopen( "hamsters.out" , "w" , stdout ) ; 75 scanf( "%d%d" , &n , &m ) , getchar() ; 76 FOR ( i , 0 , n ) 77 { 78 scanf( "%s" , Data[ i ] ) , getchar() ; 79 Len[ i ] = strlen( Data[ i ] ) ; 80 } 81 Get_Dis() ; 82 // debug 83 /* 84 FOR ( i , 0 , n ) 85 { 86 FOR ( j , 0 , n ) cout << Dis.F[ i ][ j ] << ' ' ; 87 cout << endl ; 88 } 89 */ 90 // ------- 91 FOR ( i , 0 , n + 1 ) 92 FOR ( j , 0 , n + 1 ) Cal.F[ i ][ j ] = oo ; 93 Cal.F[ n ][ n ] = 0 ; 94 for ( ; m > 0 ; m >>= 1 ) // Fast mutiply 95 { 96 if ( m & 1 ) Cal *= Dis ; 97 Dis *= Dis ; 98 } 99 long long Ans = oo ; 100 FOR ( i , 0 , n ) Ans = min( Ans , Cal.F[ n ][ i ] ) ; 101 cout << Ans << endl ; 102 return 0 ; 103 } 104 105
还有两个点死活过不了,求轻虐,以后再想办法优化吧!!