[Problem description]

A string of up to 200 characters consisting of lower-case English letters is provided (Convention; this string is input in the form of 20 letters per line, and each line must be 20 letters ). It is required to divide the string into k parts (1 <k <= 40), and the total number of words contained in each part is the maximum (the words contained in each part can partially overlap. After a word is selected, its first letter cannot be reused. For example, the string this can contain this and is. If this is selected, it cannot contain th ).

A word is in a dictionary of no more than 6 words.

The maximum number of outputs is required.

[Input file]

Put the input data in the text file input3.dat. The format is as follows:

The first row of each group has two positive integers (P, K)

P indicates the number of strings;

K indicates K parts.

The next row of P contains 20 characters.

Then there is a positive integer s, indicating the number of words in the dictionary. (1 <= S <= 6)

In the next s line, each line has a word.

[Output file]

The result is output to the screen. Each row has an integer that corresponds to the corresponding results of each group of test data.

[Input example]

1 3

Thisabookyouareaoh

4

Is

A

OK

Sab

[Output example]

7

[Problem Analysis]

I was confused when I saw this question, but I suddenly saw a breakthrough: the question says this contains this and is, but does not contain th. That is to say, a fixed start point word can only be used once in a string, even if he can make up other words, he still uses them once. For example: String: thisa

Dictionary: This is th

The string contains the word "this is th", but this and Th are used only once, that is, to enumerate the start point of the word, as long as the string starting with this start point contains a word that can start with this start point, it means that this string contains more than one word.

Taking this into consideration, it is a bit eye-catching.

In the question, K parts of the string are required, that is, after a word is truncated from a point, it may not constitute a word. For example, in the above example, a reasonable part of three parts contains at most three letters, so that the word "this" cannot be constructed.

If it is divided into five parts, it cannot even be a word.

In this way, you need to make a change to the above, the above only controls the starting point, but also needs to limit the end point in the question, after dividing several parts, each part has a different ending point.

In this way, you need to enumerate the endpoints.

Design a two-dimensional array sum [I, j] to count the number of words contained in the string from I to J

State transition equation:

Sum [I + 1, J] + 1 (s [I, j] contains words starting with s [I)

Sum [I, j] =

Sum [I + 1, J] (opposite to above)

Note: (1) Here, the Starting sequence of enumeration characters is from the end to the header.

(2) Some people regard the above as a dynamic plan, but I think it is more accurate to say that it is recursive.

The difference between finding all the sum is that the results of different division methods are obviously different. However, we can resolve the problem as a subproblem: the maximum number of words that divide a string into k parts can be seen as the last part of the string first, in the first part of the decomposition into a K-1 part, obviously, the decision is to find a way to divide the words in the K-1 section above + the words in the last section are the most.

Obviously, this problem satisfies the principle of optimization and does not satisfy the problem of no aftereffect?

For the last part of a string to be decomposed, the part before the decomposition is not even involved in the split part. In other words, no decomposition is performed to make the string less decomposed, elements that do not belong to this small string will not be used for decomposing this smaller data transfer. This satisfies the non-efficiency.

Specific Solution Process:

Design a State opt [I, j] to divide the string from 1 to J into I portions to obtain the maximum number of words. The decision is to enumerate the Split points so that the current split method can obtain the most words.

State transition equation: OPT [I, j] = max (OPT [I-1, T] + sum [t + 1, J]) (I <t <j)

Boundary Condition: OPT [1, I] = sum [1, I] (0 <I <= L)

Time Complexity: Number of States O (n2) * Number of decisions O (n) = O (N3)

#include<cstdio>#include<cstring>#include<cstdlib>#include<algorithm>using namespace std;int p, k, c;char s[300], d[7][300];int sum[300][300], dp[300][50];int check(int l, int r){ for(int i = 0; i < c; i++) { int len = strlen(d[i]); if(0 == strncmp(d[i],s+l,len)) return 1; } return 0;}int main(){ while(scanf("%d%d",&p,&k) != EOF) { int i, j, t; for(i = 0; i < p; i++) scanf("%s",s+i*20); scanf("%d",&c); for(i = 0; i < c; i++) scanf("%s",d[i]); int len = strlen(s); for(j = len - 1; j >= 0; j--) { sum[j][j] = check(j,j); for(i = j - 1; i >= 0; i--) sum[i][j] = sum[i+1][j] + check(i,j); } for(i = 0; i < len; i++) dp[i][1] = sum[0][i]; for(t = 2; t <= k; t++) for(i = t - 1; i < len; i++) for(j = 0; j < i; j++) dp[i][k] = max(dp[i][k], dp[j][k-1] + sum[j+1][i]); printf("%d\n",dp[len-1][k]); } return 0;}