P1026 统计单词个数

题目描述

给出一个长度不超过 200 的由小写英文字母组成的字母串(约定;该字串以每行 20 个字母的方式输入,且保证每行一定为 20 个)。要求将此字母串分成 k 份( 1<k≤40 ),且每份中包含的单词个数加起来总数最大(每份中包含的单词可以部分重叠。当选用一个单词之后,其第一个字母不能再用。例如字符串 this 中可包含 thisis ,选用 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\n",f[w-1][k]);
}
 

猜你喜欢

转载自www.cnblogs.com/ZUTTER/p/9299414.html