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  
复制代码

 

 

还有两个点死活过不了,求轻虐,以后再想办法优化吧!!

posted @ 2013-04-19 17:00  SYFT  阅读(147)  评论(0编辑  收藏  举报