The number P1026 statistics word [dp]

Title Description

Is given a length of not more than  200 is 2 0 letter string lowercase English letters 0 (the string in each row  20 is 2 0 letter input mode, and to ensure that each row is constant  20 is 2 0). This requires the letter string is divided into  K K parts, and the number of words included in each add up to the total number of the maximum.

Each word may be contained partially overlap. After the election with a word, its first letter can not be reused. For example, the string  this may be included  this and  is, selected  this after can not be contained  th.

Does not exceed a given word in  6 six words in the dictionary.

The maximum number of the required output.

Input Format

The first row of each group has two positive integers  P, K P , K. p rows and p represents string, K K represents a divided  K K parts.

Next  the p- the p-lines, each line has  20 2 0 characters.

Then there is again a positive integer  S S, is the number of dictionary words. The next  S S lines, each line has a word.

Output Format

. 1 an integer, respectively corresponding to each set of test data.

Sample input and output

Input # 1
1 3
thisisabookyouareaoh
4
is
a
ok
sab
Output # 1
7

 

 Thinking

  Meaning of the questions have a place under the influence of said relatively vague, is the overlap situation.

  After this you can actually use the re-election is, but can not choose the first letter of t, which is optional full main_len can not be elected.

  After about I got it to know that this is a recursive substring find string in the meet can find the word in the dictionary and can appear a few words.

  A sum [i] [j] in the string to a front section i ~ j within a few words.

  With F [i] [j] to represent the maximum number of characters in the i-th word segment j cut obtainable.

  Obviously it can be transferred as follows:

        f [ i ] [ k ] = max ( f [ i ] [ k ] , f [ j ] [ k - 1] + sum [ 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 ;
}

Guess you like

Origin www.cnblogs.com/orangeko/p/12537449.html