La palabra estadísticas número P1026 [dp]

título Descripción

Se le da una longitud de no más de  200 es 2 0 cadena de letras minúsculas inglés 0 (la cadena en cada fila  20 es 2 modo de entrada de 0 carta, y para asegurar que cada fila es constante  20 es 2 0). Esto requiere la letra cadena se divide en  K K partes, y el número de palabras incluidas en cada suman al total del máximo.

Cada palabra puede estar contenido parcialmente solapamiento. Después de la elección con una palabra, su primera carta no puede ser reutilizado. Por ejemplo, la cadena  this puede incluirse  this y  is, selecciona  this después no puede ser contenida  th.

No exceda de una palabra dada en  6 seis palabras en el diccionario.

El número máximo de la salida requerida.

Formato de entrada

La primera fila de cada grupo tiene dos números enteros positivos  P, K P , K. p filas y p representa la secuencia, K K representa un divididas  K K partes.

Siguiente  la p- los p-líneas, cada línea tiene  20 2 0 caracteres.

Entonces allí de nuevo es un entero positivo  S S, es el número de diccionario de palabras. Los próximos  S S líneas, cada línea tiene una palabra.

Formato de salida

. 1 un número entero, que corresponden respectivamente a cada conjunto de datos de prueba.

entrada y salida de la muestra

Entrada # 1
1 3 
thisisabookyouareaoh 
4 
es 
un 
ok 
SAB
Salida # 1
7

 

 pensamiento

  Significado de las preguntas tienen un lugar bajo la influencia de dicho relativamente vaga, es la situación de solapamiento.

  Después de esta realidad se puede utilizar la reelección es, pero no se puede elegir la primera letra T, que es main_len completo opcional no pueden ser elegidos.

  Después de cerca lo tengo que saber que este es un recursivo cadena subcadena hallazgo en el encuentro puede encontrar la palabra en el diccionario y pueden aparecer algunas palabras.

  Una suma [i] [j] de la cadena a una sección frontal i ~ j dentro de unas pocas palabras.

  Con F [i] [j] para representar el número máximo de caracteres en el segmento i-ésima palabra j cortar obtenible.

  Obviamente, se puede transferir la siguiente manera:

        f [i] [k] = max (f [i] [k], f [j] [k - 1] + suma [i - 1] [j]); 其中 k ∈ [2, min (k, j + 1)];

 

CÓDIGO

 

 
#include   < bits / STDC ++. h >
#define   dbg ( x )  cout  <<   #x   <<   " = "   <<  x  <<  endl
#define  eps  1 e - 8
#define  pi  acos( - 1.0 )

using  namespace std ;
typedef  long  long LL ;

const  int inf  =  0x 3f3f3f3f ;

template < class T > inline  void  read(& res )
{
     char c ;T flag = 1 ;
     while((c = getchar()) < ' 0 ' ||c > ' 9 ' )if(c == ' - ' )flag =- 1 ;res =c - ' 0 ' ;
     while((c = getchar()) >= ' 0 ' &&c <= ' 9 ' )res =res * 10 +c - ' 0 ' ;res *=flag ;
}

namespace _buff  {
     const  size_t BUFF  =  1  <<  19 ;
     char  ibuf [BUFF ],  *ib  = ibuf ,  *ie  = ibuf ;
     char  getc()  {
         if  (ib  == ie )  {
            ib  = ibuf ;
            ie  = ibuf  +  fread(ibuf ,  1 , BUFF , stdin );
         }
         return ib  == ie  ?  - 1  :  *ib ++ ;
     }
}

int  qread()  {
     using  namespace _buff ;
     int ret  =  0 ;
     bool pos  =  true ;
     char c  =  getc();
     for  (;  (<  ' 0 '  || c  >  ' 9 ' )  && c  !=  ' - ' ; c  =  getc())  {
         assert( ~c );
     }
     if  (==  ' - ' )  {
        pos  =  false ;
        c  =  getc();
     }
     for  (; c  >=  ' 0 '  && c  <=  ' 9 ' ; c  =  getc())  {
        ret  =  (ret  <<  3 )  +  (ret  <<  1 )  +  (^  48 );
     }
     return pos  ? ret  :  -ret ;
}

int p , k ;

string a , b ;
string  ss [ 15 ];

int  sum [ 1000 ][ 1000 ];
int  f [ 1000 ][ 1000 ];

int  main()
{
     read(p );read(k );
     for  (  int i  =  1 ; i  <= p ;  ++)  {
        cin  >> b ;
        a  += b ;
     }
     int main_len  =  a .size();
     int n ;
     read(n );
    vector <int>  len(+  7 );
     for  (  int i  =  1 ; i  <= n ;  ++)  {
        cin  >>  ss [i ];
         len [i ]  =  ss [i ].size();
     }
     for  (  int i  =  0 ; i  < main_len ;  ++)  {
         for  (  int j  = i ; j  < main_len ;  ++)  { //todo:枚举子段
             for  (  int k  = i ; k  <= j ;  ++)  {
                 int ok  =  1 ;
                 for  (  int z  =  1 ; z  <= n ;  ++)  {
                     if(+  len [z ]  -  1  > j )
                         continue;
                     for  (  int w  =  0 ; w  <  len [z ];  ++)  {
                         if(==  len [z ]  -  1  &&  a [+ w ]  ==  ss [z ][w ])  {
                            ok  =  0 ;
                             break;
                         }
                         if( a [+ w ]  !=  ss [z ][w ])  {
                             break;
                         }
                     }
                     if( !ok )
                         break;
                 }
                 if( !ok )  {
                     sum [i ][j ] ++ ;
                 }
             }
         }
     }
    // for ( int i = 0; i < main_len; ++i ) {
    //     for ( int j = 0; j < main_len; ++j ) {
    //         printf("sum[%d][%d]:%d\n",i, j, sum[i][j]);
    //     }
    // }
     for  (  int i  =  0 ; i  < main_len ;  ++)  {
         f [i ][ 1 ]  =  sum [ 0 ][i ];
         for  (  int j  =  0 ; j  < i ;  ++)  {
             for  (  int k  =  2 ; k  <=  min(k , j  +  1 );  ++)  {
                 f [i ][k ]  =  max( f [i ][k ],  f [j ][-  1 ]  +  sum [+  1 ][i ]);
             }
         }
     }
    cout  <<  f [main_len  -  1 ][k ]  << endl ;
     return  0 ;
}

Supongo que te gusta

Origin www.cnblogs.com/orangeko/p/12537449.html
Recomendado
Clasificación