统计单词个数

来源:互联网 发布:python 书籍 知乎 2016 编辑:程序博客网 时间:2024/06/08 11:25

统计单词个数

Description

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

Input

第一行有2个正整数p,k。p表示字串的行数;k表示分为k个部分。

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

再接下来有一个正整数s,表示字典中单词个数。(1≤s≤6)

接下来的s行,每行均有一个单词。

Output

仅一行,一个整数,表示划分出来的最多单词个数。

Sample Input

1 3
thisisabookyouareaoh
4
is
a
ok
sab

Sample Output

7

Hint

如下方式划分字符串:
this/isabookyoua/reaoh

题解:

dp[i][t] 代表前 i 个字母分成 t 段的最大单词数。1<=t<=k 
w[i][j] 代表 区间[i,j]的最大单词数。

先求出 w, 再求 dp。

w[i][j] 不能共同前缀, 所以从后往前更新,验证前缀。 
w[i][j] = w[i+1][j]+1 (当存在以i开头的单词完全在 [i,j] 内) 
w[i][j] = w[i+1][j] 不存在

然后 dp[i][t] = max(dp[i][t], dp[j][t-1]+w[j+1][i]); 

#include<stdio.h>#include<string.h>#define max(a,b) a>b?a:bchar s[200],word[7][200];int dp[200][200],w[200][200],p,k,n,wordlen[7];int check(int i,int j){//检查开头新加字母s[i]区间[i,j]单词是否加一 int k;for(k=0;k<n;k++){if((memcmp(word[k],s+i,wordlen[k])==0)&& (wordlen[k]<=(j-i+1))){return 1;}}return 0;}void calw(){//求w[i][j] int i,j;for(j==p*20-1;j>=0;j--){w[j][j]=check(j,j);for(i=j-1;i>=0;i--){w[i][j]=w[i+1][j]+check(i,j);}} }void caldp(){//动态规划 int i,j,t;for(i=0;i<p*20;i++){dp[i][1]=w[0][i];}for(t=2;t<=k;t++){for(i=t-1;i<p*20;i++){for(j=t-1;j<i;j++){dp[i][t]=max(dp[i][t],dp[j][t-1]+w[j+1][i]);}}}}int main(){int i,j;scanf("%d%d",&p,&k);for(i=0;i<p;i++){scanf("%s",s+i*20);}scanf("%d",&n);for(i=0;i<n;i++){scanf("%s",word[i]);wordlen[i]=strlen(word[i]);}calw();//求w[i][j]caldp();//动态规划 printf("%d",dp[p*20-1][k]); }


1 0