题目描述
给出一个长度不超过 200 的由小写英文字母组成的字母串(约定;该字串以每行 20 个字母的方式输入,且保证每行一定为 20 个)。要求将此字母串分成 k 份( 1<k≤40 ),且每份中包含的单词个数加起来总数最大(每份中包含的单词可以部分重叠。当选用一个单词之后,其第一个字母不能再用。例如字符串 this 中可包含 this 和 is ,选用 this 之后就不能包含 th )。
单词在给出的一个不超过 6 个单词的字典中。
要求输出最大的个数。
输入输出格式
输入格式:
每组的第一行有 2 个正整数( p,k )
p 表示字串的行数, k 表示分为 k 个部分。
接下来的 p 行,每行均有 20 个字符。
再接下来有 1 个正整数 sss ,表示字典中单词个数。( 1≤s≤6 )
接下来的 s 行,每行均有 1 个单词。
输出格式:
1个整数,分别对应每组测试数据的相应结果。
输入输出样例
输入样例#1: 复制
1 3 thisisabookyouareaoh 4 is a ok sab
输出样例#1: 复制
7
首先一定要夸赞一下水出境界的数据,让我这种蒟蒻用5重循环把这道题水过去了╮(╯▽╰)╭
5重循环后就变成了一道简单dp
f[i][j]表示到第个字符,分成j组后的最大值
f[i][j]=max(f[l-1][j-1]+z[l][i])
每次穷举l然后暴力穷举q(l~i)中每个字母能否作为首字母匹配单词求出z[l][i]
#include<iostream> #include<stdio.h> #include<cstring> using namespace std; int i,m,n,j,k,b[10],w,ee,l,q,p,f[201][50],ans,o,v[10001]; char c[201],a[100001],d[10][201]; bool bl; int main() { w=n*20; for(j=0;j<n;j++) { cin>>c; for(i=0;i<20;i++) a[j*20+i]=c[i]; } scanf("%d",&m); for(i=1;i<=m;i++) { cin>>d[i]; b[i]=strlen(d[i]); } for(i=0;i<w;i++) for(j=1;j<=min(i,k);j++) for(l=j-1;l<=i;l++) { if(i==5) { ee=0; } ans=0; for(q=l;q<=i;q++) { bl=0; for(p=1;p<=m;p++) { int t=q,e=0; while((a[t]==d[p][e])&&(t<=i)&&(e<b[p])) t+=1,e+=1; if(e==b[p]) { bl=1; break; } } if(bl) ans+=1; } f[i][j]=max(f[i][j],ans+f[l-1][j-1]); } printf("%d ",f[w-1][k]); }