2349 - 统计单词个数

通过次数

0

提交次数

0

时间限制 : 1 秒 内存限制 : 125 MB

给出一个长度不超过200的由小写英文字母组成的字母串(约定:该字串以每行20个字母的方式输入,且保证每行一定为20个)。要求将此字母串分成k份(1<k<=40),且每份中包含的单词个数加起来总数最大(每份中包含的单词可以部分重叠。当选用一个单词之后,其第一个字母不能再用。例如字符串this中可包含this和is,选用this之后就不能包含th)。

单词在给出的一个不超过6个单词的字典中。

要求输出最大的个数。


题目输入

每个测试文件只包含一组测试数据,其格式如下:

每组的第一行输入两个正整数p和k,p表示字串的行数,k表示分为k个部分。

接下来的p行,每行均有20个字符。

再接下来一行输入一个正整数s(1<=s<=6),表示字典中单词个数。

接下来的s行,每行输入一个单词。

<br />

题目输出

对于每组输入数据,输出一个整数,分别对应每组测试数据的相应结果。

下面是对样例数据的说明:

样例数据中对字母串分割的方式是:this/isabookyoua/reaoh


输入/输出样例

输入格式

1 3
thisisabookyouareaoh
4
is
a
ok
sab

输出格式

7

C++解答

#include<cstdio>
#include<cstring>
int word[201][201],dp[201][201][41];
char c[21],w[6][10],c0[201],c1[201];
int d,p,k,s,Max,le[6],len;
int main(){
	int i,j,l,m,yes,x,st;
		scanf("%d%d",&p,&k);
  		for(j=0;j<p;j++){
   			scanf("%s",c);
   			if(!j)strcpy(c0, c);
   			else strcat(c0, c);
  		}
  		len=strlen(c0);
  		scanf("%d",&s);
  		for(j=0;j<s;j++){
   			scanf("%s",w[j]);
   			le[j]=strlen(w[j]);
  		}
  		for(i=0;i<len;i++)for(j=0;j<len;j++)word[i][j]=0; 
  		for(i=len-1;i>=0;i--)for(j=len-1;j>=0;j--){
    			for(l=0;l<s;l++){
     				yes=0;
     				if(c0[j]==w[l][0]&&le[l]<=i-j+1){
      					yes=1; 
      					for(m=0;m<le[l];m++)
       						if(c0[j+m]!= w[l][m]){yes=0;break;}
     				}
     				if(yes==1)break;
    			}
    			if(yes==1)word[j][i]=word[j+1][i]+1; 
    			else word[j][i]=word[j+1][i];
   			}
  		for(st=1;st<=k;st++)for(i=0;i<len-st+1;i++)for(j = i+st-1; j < len; j++){
     				if(st==1){
						dp[i][j][st]=word[i][j]; 
						continue; 
					}
     			for(Max=0,l=i+st-2;l<j;l++){
      				x=dp[i][l][st-1]+word[l+1][j];
      				if(x>Max)Max=x;
     			}
     			dp[i][j][st]=Max;
    			}
  		printf("%d\n",dp[0][len-1][k]);
 	return 0;
}