统计单词数

                                                                   统计单词个数

Description

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

Input

第一行有二个正整数(p,k),p表示字串的行数;,k表示分为k个部分。
接下来的p行,每行均有20个字符。
再接下来有一个正整数s,表示字典中单词个数。(1<=s<=6)
接下来的s行,每行均有一个单词。

Output

结果输出至屏幕,每行一个整数,分别对应每组测试数据的相应结果。

Sample Input

2 1
thisisappleisthisthe
oopbooktheisurrtoywe
4
is
of
the
book
Sample Output

转移方程f[i][j]=max{f[i-1][k]+word[k+1][j]}

f[i][j]表示前j个字符分成i份的最多单词数,word[k][j]表示第k个到第j个字符间的单词数目,它由以下方程转移:

if(存在以a[k-1]打头的单词,且长度不超过j-k+1)

word[k][j]=word[k+1][j]+1;

else 

word[k][j]=word[k+1][j];

 

 
ContractedBlock.gifExpandedBlockStart.gif代码
1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<string.h>
4 int f[41][200],word[201][201],n,k,s;
5 char a[200],dic[7][1000];
6
7 int main(){
8 FILE *in,*out;
9 int i,j,max,z,flag,t,x;
10 char list[20];
11 in=fopen("input31.dat","r");
12 out=fopen("output.out","w");
13 fscanf(in,"%d%d",&n,&k);
14 for(i=1;i<=n;i++)
15 {
16 fscanf(in,"%s",list);
17 strcat(a,list);
18 }
19 n=20*n;
20 fscanf(in,"%d",&s);
21 for(i=1;i<=s;i++)
22 fscanf(in,"%s",dic[i]);
23
24 memset(f,0,sizeof(f));
25 memset(word,0,sizeof(word));
26 for(z=1;z<=s;z++)
27 if(dic[z][0]==a[n-1]&&strlen(dic[z])==1)
28 word[n][n]=1;
29
30 for(i=n-1;i>=1;i--)
31 for(j=i;j<=n;j++)
32 {
33 flag=0;
34 t=j-i+1;
35 for(z=1;z<=s;z++)
36 if(dic[z][0]==a[i-1]&&strlen(dic[z])<=t)
37 {
38 for(x=1;x<strlen(dic[z]);x++)
39 if(a[i-1+x]!=dic[z][x])break;
40 if(x==strlen(dic[z]))flag=1;
41 }
42 word[i][j]=word[i+1][j]+flag;
43 }
44
45
46 for(i=1;i<=k;i++)
47 for(j=i;j<=n;j++)
48 {
49 for(z=i-1;z+1<=j;z++)
50 if(f[i][j]<f[i-1][z]+word[z+1][j])
51 f[i][j]=f[i-1][z]+word[z+1][j];
52 }
53
54 fprintf(out,"%d\n",f[k][n]);
55 fclose(in);fclose(out);
56 return 0;
57 }

 

 

转载于:https://www.cnblogs.com/aiyite826/archive/2010/08/08/1794949.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值