Les statistiques P1026 numéro mot [dp]

Titre description

Est donné une longueur maximale de  200 est 2 0 lettre minuscule string lettres anglaises 0 (la chaîne dans chaque ligne  20 est 2 mode d'entrée 0 lettre, et veiller à ce que chaque ligne est constante  20 est 2 0). Cela nécessite la chaîne lettre est divisée en  K parties K, et le nombre de mots inclus dans chaque ajouter au nombre total de maximum.

Chaque mot peut être contenu se chevauchent partiellement. Après l'élection d'un mot, sa première lettre ne peut pas être réutilisé. Par exemple, la chaîne  this peut être inclus  this et  is, sélectionné  this après ne peut pas être contenu  th.

Ne dépasse pas un mot donné dans  6 six mots dans le dictionnaire.

Le nombre maximum de la puissance requise.

Format d'entrée

La première rangée de chaque groupe dispose de deux nombres entiers positifs  P, K P , K. p lignes et de p représente chaîne, K K représente un fractionnées  K parties K.

Suivant  le p- les p lignes, chaque ligne a  20 2 0 caractères.

Ensuite , il y a encore un entier positif  S S, est le nombre de mots du dictionnaire. La suite  S lignes S, chaque ligne a un mot.

Format de sortie

. 1 un nombre entier, correspondant respectivement à chaque ensemble de données d'essai.

l'entrée et la sortie d'échantillon

Entrée # 1
1 3 
thisisabookyouareaoh 
4 
est 
un 
ok 
sab
Sortie # 1
sept

 

 pensée

  Signification des questions ont lieu sous l'influence de ladite est la situation de chevauchement relativement vague,.

  Après cela, vous pouvez réellement utiliser la réélection est, mais ne peut pas choisir la première lettre de t, ce qui est en option main_len complet ne peuvent pas être élus.

  Après environ je suis arrivé à savoir que ceci est une chaîne de découverte de sous-chaîne récursive dans la rencontre peut trouver le mot dans le dictionnaire et peut apparaître quelques mots.

  Une somme [i] [j] dans la chaîne à une partie avant i ~ j en quelques mots.

  Avec F [i] [j] pour représenter le nombre maximal de caractères dans le i-ième segment de mot j coupé pouvant être obtenu.

  De toute évidence, il peut être transféré comme suit:

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

 

CODE

 

 
#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 ;
}

Je suppose que tu aimes

Origine www.cnblogs.com/orangeko/p/12537449.html
conseillé
Classement