番号P1026統計語[DP]

タイトル説明

以上の長さを与えられた  200 2 0 文字列を英語の文字を0小文字(各行の文字列  20が2 0文字入力モード、及び各行が一定であることを保証するために、  20 2 0)。この文字列がに分割されている文字必要  K Kの部分を、それぞれに含まれる単語の数が最大の合計数まで追加します。

各ワードは、部分的にオーバーラップ含まれていてもよいです。単語と選挙後、その最初の文字を再利用することはできません。例えば、文字列が  this 含まれていてもよい  this と  is、選択された  this 缶が含まれない後  th

与えられた単語超えない  6つの辞書に6言葉を。

要求出力の最大数。

入力形式

各グループの最初の行は、2つの正の整数有する  P、K P Kを p個の行およびpは、文字列を表し、K K分割表す  K K部品。

次  P- Pライン、各ラインが有する  20の2つの0文字。

そこ正の整数再び  S Sは、辞書の単語の数です。次の  S S線は、各行はワードを有します。

出力フォーマット

1 それぞれのテストデータの各セットに対応する整数。

サンプル入力と出力

入力#1
3 1 
thisisabookyouareaoh 
4が
ある
OK 
SAB
出力#1
7

 

 思考

  質問の意味と比較的曖昧の影響で場所を持って、オーバーラップ状況です。

  この後には、実際に再選挙があるが、オプションフルmain_lenを選出することができないトンの最初の文字を、選択することはできません使用することができます。

  後、私はそれが、これは出会いで再帰部分文字列検索文字列が辞書に単語を見つけることができますし、いくつかの単語を表示することができていることを知りました。

  フロント部分に文字列で合計[I] [J] I〜いくつかの単語内のJ。

  F [I] [j]を用いて得られる切断i番目のワード・セグメントjにおける文字の最大数を表現します。

  次のように明らかにそれを転送することができます。

        F [i]が[K] = MAX(F [i]が[K]、F [j]は[K - 1] +和[I - 1] [J])。其中K∈[2、分(K、J + 1)]。

 

コード

 

 
#include   < ビット/ 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 ;
}

おすすめ

転載: www.cnblogs.com/orangeko/p/12537449.html