[Luogu P1026 count the number of words] problem solution

Count the number of words

Title Description

It is given a length of not more than 200 is 2 0 letter string lowercase English letters 0 (convention; the string in each row 20 is letter input mode, and must ensure that each row is 2 0).

This requires the letter string is divided into k parts ( . 1 <= k . 4 0), and the number of words included in each maximum combined total number of words (contained in each may partially overlap.

After the election with a word, its first letter can not be reused. String e.g. this can be included in this and I s, the choice of T H I then s can not contain T H).

No more than a word in a given 6 -word 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 denotes into k parts.

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

Then there again . 1 positive integer s, indicates the number of words in the dictionary. ( . 1 S . 6)

The next s lines each have 1 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

Description / Tips

this/isabookyoua/reaoh

 

Before solving the problem, you can first understand the following functions of the STL.

From the subscript of y x length start character string (first letter subscript 0) 1. s.substr (x, y) taken in s.

2. s.find (t) in s t to find the string, returns 0 if found, return a maximum value can not be found.

3. s.length () returns the length of the string s. 

 

In addition, analysis of the meaning of problems can be clearly determined to be a range dp problem.

We remember

sum [i] [j] q as a string interval [i, j] the number that appears in the word.

DP [i] [j] to be completed before processing letters i, j is divided into intervals, the number of words can be obtained.

So get transfer equation:

dp[i][j] = max(dp[i][j] , dp[t-1][j-1] + sum[t][i]), t∈(j,i)

Because divided into intervals j-1, j-1 needs to show the most letters, so t dp starts from j.

 

After the transfer of the most difficult equation to solve, to think about how we initialized.

He said the subject of the request is only the beginning of a letter of a word.

So we consider the reverse.

First, we enumerate from right to left right point range.

Then from right to left in the enumeration left point range, to inherit the left point on a sum, it is determined whether the beginning of the current of the left point as a word.

If you can +1.

 

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
using namespace std;
int dp[1000][100],sum[1000][1000];
int p,k,m,len;
string s="0",ch,a[1000];
inline BOOL Check ( int L, int R & lt) {// determines whether there is a word beginning with l.
    String X = s.substr (L, + L-R & lt . 1 );
     for ( int I = . 1 ; I <= m; I ++ )
         IF (x.find (A [I]) == 0 ) return  to true ;
     return  to false ;
}
int main ()
{
    int i,j,t;
    scanf("%d%d",&p,&k);
    for(i=1;i<=p;i++){
        cin>>ch;
        s+=ch;
    }
    scanf("%d",&m);
    for(i=1;i<=m;i++) cin>>a[i];
    len=s.length()-1;
    for(i=len;i>=1;i--)
    for(j=i;j>=1;j--){
        SUM [J] [I] = SUM [J + . 1 ] [I]; // inherited a front section
         IF (Check (J, I))
        sum[j][i]++;
    }
    for(i=1;i<=len;i++)
        for(j=1;j<=k&&j<=i;j++)
            for(t=j;t<=i;t++)//dp核心
                dp[i][j]=max(dp[i][j],dp[t-1][j-1]+sum[t][i]);
    printf("%d",dp[len][k]);
}

 

Guess you like

Origin www.cnblogs.com/quitter/p/11720772.html