题目描述

给出一个长度不超过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行,每行均有一个单词。

输出格式:

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

输入输出样例

输入样例#1:

1 3
thisisabookyouareaoh
4
is
a
ok
sab
输出样例#1:

7

不得不说最开始我连题意都没看懂,2333。

大概意思是说,给你一串字符,你将这个字符划分成k块,使每一块包含的单词数总和最多。
我的想法是用两次动态规划,第一次设置一个数组cnt_word[i][j](不要吐槽为什么名字那么长)
它表示从i号到j号包含多少单词数,然后就很好推,如果从i号到j号有以i号为头的字母,那么cnt_word[i][j]=cnt_word[i+1][j]+1,
如果不存在,那么就是cnt_word[i][j]=cnt_word[i+1],
可以用strstr来判断是否包含,并且判断是否以a[i]开头,
接下来就很好推了,就是枚举枚举区间。
注意第一个细节,字符串编号是从0开始,那么,范围应是0-(p*20-1),
第二,枚举区间时要注意,不要让某个区间为空,那样一定会错(如果没错,不要拆穿我。)
好了,看不懂的看我代码吧,我会加上注释。

 #include <iostream>
#include <fstream>
#include <cstdlib>
#include <cstring>
#include <string>
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
using namespace std;
int cnt_hang=,cnt_fen=,cnt_words=;
char a[];
char words[][];
int cd_words[]={};//记录每个单词的长度
int cnt_word[][]={};//表示从某开头到某时,能有多少单词.
int jiyi[][]={};
void jilv( );
int cha(int ks,int js);
int dg(int ks,int fen); void jilv( ){
for(int y=cnt_hang*-;y>=;y--)//注意范围
for(int x=y;x>=;x--){
if(cha(x,y)!=)cnt_word[x][y]=cnt_word[x+][y]+;
else cnt_word[x][y]=cnt_word[x+][y];
}
return;
} int cha(int ks,int js){
for(int x=;x<=cnt_words;x++){
char *p=strstr(&a[ks],words[x]);
//表示询问单词x是否是从a[ks]到结束这一段的字符的字串.如果不是,会返回0,如果是 就会返回str2在str1中首次出现的地址
if(p!=&&p-&a[ks]==&&cd_words[x]<=js-ks+)return ;
//如果是字串,且是以a[ks]的字串,并且是在ks到js这一段以内的字串,那么就返回1,
}
return ;
} int dg(int ks,int fen){
//不要吐槽我为什么不用递推,这下面就很好理解了,就是枚举区间.
if(fen==)return cnt_word[ks][cnt_hang*-];
if(jiyi[ks][fen]!=-)return jiyi[ks][fen];
for(int x=ks;x<=cnt_hang*-fen;x++)
jiyi[ks][fen]=max(jiyi[ks][fen],dg(x+,fen-)+cnt_word[ks][x]);
return jiyi[ks][fen];
} int main(int argc, char *argv[]) {
cin>>cnt_hang>>cnt_fen;
cin>>a;
for(int x=;x<=cnt_hang;x++){
char b[];
cin>>b;
strcat(a,b);//表示将b接在a串后面. 注,大多str开头的函数都必须用<cstring>的头文件
}
//cout<<a<<endl;
cin>>cnt_words;
for(int x=;x<=cnt_words;x++){
cin>>words[x];
cd_words[x]=strlen(words[x]);//表示计算长度
}
jilv( );//第一个动归
memset(jiyi,-,sizeof(jiyi));
int ans=dg(,cnt_fen); //就是一个枚举区间
cout<<ans;
return ;
}

洛谷 P1026 统计单词个数的更多相关文章

  1. 洛谷 P1026 统计单词个数 Label:dp

    题目描述 给出一个长度不超过200的由小写英文字母组成的字母串(约定;该字串以每行20个字母的方式输入,且保证每行一定为20个).要求将此字母串分成k份(1<k<=40),且每份中包含的单 ...

  2. [NOIP2001] 提高组 洛谷P1026 统计单词个数

    题目描述 给出一个长度不超过200的由小写英文字母组成的字母串(约定;该字串以每行20个字母的方式输入,且保 证每行一定为20个).要求将此字母串分成k份(1<k<=40),且每份中包含的 ...

  3. 洛谷P1026 统计单词个数【区间dp】

    题目:https://www.luogu.org/problemnew/show/P1026 题意: 给定一个字符串,要求把他分成k段.给定s个单词,问划分成k段之后每段中包含的单词和最大是多少. 一 ...

  4. 洛谷 P1026 统计单词个数 (分组+子串预处理)(分组型dp再次总结)

    一看完这道题就知道是划分型dp 有两个点要注意 (1)怎么预处理子串. 表示以i为开头,结尾在j之前(含),有没有子串,有就1,没有就0 (2)dp的过程 这种分成k组最优的题目已经高度模板化了,我总 ...

  5. luogu P1026 统计单词个数

    题目链接 luogu P1026 统计单词个数 题解 贪心的预处理母本串从i到j的最大单词数 然后dp[i][j] 表示从前i个切了k次最优解 转移显然 代码 #include<cstdio&g ...

  6. P1026 统计单词个数——substr

    P1026 统计单词个数 string 基本操作: substr(x,y) x是起始位置,y是长度: 返回的是这一段字符串: 先预处理sum[i][j],表示以i开头,最多的单词数: 从后往前寻找,保 ...

  7. [luogu]P1026 统计单词个数[DP][字符串]

    [luogu]P1026 统计单词个数 题目描述 给出一个长度不超过200的由小写英文字母组成的字母串(约定;该字串以每行20个字母的方式输入,且保证每行一定为20个).要求将此字母串分成k份(1&l ...

  8. P1026 统计单词个数 (动态规划)

    题目描述 给出一个长度不超过200的由小写英文字母组成的字母串(约定;该字串以每行20个字母的方式输入,且保证每行一定为20个).要求将此字母串分成k份(1<k<=40),且每份中包含的单 ...

  9. 洛谷 P1308 统计单词数【字符串+模拟】

    P1308 统计单词数 题目描述 一般的文本编辑器都有查找单词的功能,该功能可以快速定位特定单词在文章中的位置,有的还能统计出特定单词在文章中出现的次数. 现在,请你编程实现这一功能,具体要求是:给定 ...

随机推荐

  1. php文件缓存

    1.最新代码 <?php class cache { private static $_instance = null; protected $_options = array( 'cache_ ...

  2. jQuery慢慢啃之事件对象(十一)

    1.event.currentTarget//在事件冒泡阶段中的当前DOM元素 $("p").click(function(event) { alert( event.curren ...

  3. 从一个标准 url 里取出文件的扩展名

    在php预定义函数中有一个叫做"pathinfo()"的函数,专门用于返回文件路径信息的. 那好,我们就来看一下它能为我们做些什么?       语法:pathinfo($url_ ...

  4. centos下的lnmp环境搭建

    1.配置centos的第三方yum源,因为原始的yum是无法安装nginx的 wget http://www.atomicorp.com/installers/atomic  下载atomic yum ...

  5. hw-text1

    Text 1 测试题 python是什么类型的语言? 解释型语言,是脚本语言 百娘(脚本语言是为了缩短传统的编写-编译-链接-运行(edit-compile-link-run)过程而创建的计算机编程语 ...

  6. github避免每次输入账户密码

    方法1: 显示所有隐藏目录,找到目录./git下的文件config文件,通过文本方式打开,在最前面添加如下两行.之后再次输入一次密码后就会记住账号密码. [credential]     helper ...

  7. 基于TCP的NAT子网穿透实验

    不得不说,在国内IP紧缺的现状下,NAT发挥了无比巨大的作用:它以把IP和端口重新分配的方式,满足了广大人民群众上网的强烈需求.但是对于个人服务器以及在内网中基于网络的嵌入式设备,却是个比较尴尬的事情 ...

  8. winform下载网页源码

    public partial class Form1 : Form{public Form1(){InitializeComponent();} private void button1_Click( ...

  9. 【zz】C++中struct与class的区别

    转载来源:http://blog.sina.com.cn/s/blog_48f587a80100k630.html C++中的struct对C中的struct进行了扩充,它已经不再只是一个包含不同数据 ...

  10. Innodb和MyISAM比较

    Innodb和MyISAM比较 (1)MyISAM类型的表强调的是性能,其执行速度比InnoDB类型更快 (2)MyISAM不支持事务.外键,InnoDB支持事务和外键 (3)MyISAM使用的表级锁 ...