[Luogu P1026は、単語の数をカウントする]問題解決

単語の数を数えます

タイトル説明

これは、以下の長与えられる200である2 0 小文字の英文字0の文字列(慣例;各行の文字列20は、文字入力モード、及び各列であることを保証しなければならない2 0)。

これは、文字列をに分割される必要のk (部品1 <= k個の4。0)、および単語数は、それぞれに含まれる単語(部分的に重なってもよいの各最大組み合わせ数に含まれます。

単語と選挙後、その最初の文字を再利用することはできません。文字列は、例えば、これは、中に含まれ得るI Sの選択T Hは、I 、次いでSは含めることはできませんT )Hを。

与えられた中の単語を超えない6 -word辞書。

要求出力の最大数。

入力形式

各グループの最初の行が有する2つの正の整数(P、K P K)を

p個の行およびpは文字列を表し、kはに表すk個の部品。

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

そこ再び。1つの正の整数S、辞書内の単語の数を示します。1 S 6)

行はそれぞれ持っている1 ワード。

出力フォーマット

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

サンプル入力と出力

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

説明/ヒント

この/ isabookyoua / reaoh

 

問題を解決する前に、まずSTLの以下の機能を理解することができます。

Y×長開始文字列(最初の文字の添え字0)秒で撮影した1 s.substr(x、y)の添字から。

文字列を検索するS Tの2 s.find(t)は、見つかった場合は0を返し、最大値を見つけることができない返します。

3. s.length()は、文字列sの長さを返します。 

 

また、問題の意味の分析は明らかに範囲DPの問題であると判断することができます。

私たちは覚えています

文字列の間隔との和[I] [J] Q [I、J]単語で表示される番号。

DP [I] [j]は文字iを処理する前に完了すること、jが区間に分割され、単語の数を得ることができます。

だから、伝達方程式を得ます:

DP [I] [J] = MAX(DP [I]、[J]、DP [T-1] [J-1] +和[T] [I])、  t∈(j、i)に対して

区間J-1に分かれているのでDPは、Jから始まるトンので、J-1は、ほとんどの文字を表示する必要があります。

 

我々は初期化方法を考えるために、解決するために最も困難な方程式の転送後。

彼は要求の対象は、単語の文字の始まりに過ぎないと述べました。

だから我々は、逆を考えます。

まず、我々は右のポイント範囲を右から左に列挙する。

次に列挙左ポイント範囲で右から左に、合計で左の点を継承するために、それが単語として左のポイントの現在の始まりかどうかが決定されます。

あなたは+1することができます。

 

#include <iostreamの> 
する#include <cstdioを> 
する#include <CStringの> 
する#include < ストリング >
 使用して 名前空間STD;
 int型 DP [ 1000 ] [ 100 ] SUM [ 1000 ] [ 1000 ];
 int型のP、K、M、lenの;
 文字列 S = " 0 "、CH、[ 1000年]; 
インラインBOOLのチェック(int型 L、INT R&LT){// Lを開始する単語があるか否かを判定する。
    ストリング X = s.substr(L、+ L-R&LT 1。 のためのINTI = 1 ; I <= M; iは++ 場合(x.find([I])== 0を返す 返す ; 
} 
int型のmain()
{ 
    int型I、J、T。
    scanf関数(" %dの%のD "、&​​P&K)。
    (i = 1 ; I <= P、iは++ ){ 
        CIN >> CH。
        S + = CH。
    } 
    のscanf(" %dの"、&M)。
    (i = 1 ; I <= M; iは++)CIN >>[I]。
    LEN = s.length() - 1 ;
    (; I> = I = LEN 1 ; i-- のための(; J> = J = 1 ; j-- ){ 
        和[j]は[I] =和[J + 1 ] [I]; //继承前一个区间
         場合(チェック(j、i)に対して)
        合計[J] [I] ++ ; 
    } 
    のための(I = 1 iは++; iは= LEN < のための(J = 1 ; J <= K && J <= I; J ++ のための(; T <= I; T = J T ++ )// DP核心
                DP [I ] [J] = MAX(DP [I]、[J]、DP [T- 1 ] [J-1 ] + 和[T] [I])。
    printf(" %dの" 、DP [LEN] [K])。
}

 

おすすめ

転載: www.cnblogs.com/quitter/p/11720772.html