题目描述

给出一个长度不超过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. Linux的more、less

    2.more 文件内容或输出查看工具: more 是我们最常用的工具之一,最常用的就是显示输出的内容,然后根据窗口的大小进行分页显示,然后还能提示文件的百分比: de>[root@localho ...

  2. cell的循环使用

    cell的循环利用:(对cell的简单优化) 1.创建一个标示(Identifier),用于区分缓存池里的不同cell. 2.去缓存池里拿自己对应的cell,用到dequeueReusableCell ...

  3. 【实习记】2014-08-24实习生无法映射磁盘替代方案rsync+非默认端口22设置

    正职开发人员有两个电脑,一个办公网的,一个开发网的.通过samba服务在开发网机器上映射编译环境机的磁盘没有问题. 开发岗实习生使用虚拟机做跳板方式登录编译环境机.上面的方法不能用. 替代方法:rsy ...

  4. iphone5手机端内容超出iphone6没问题且超出内容为http://.....网址

  5. 深入了解jquery中的键盘事件

    很多时候,我们需要获取用户的键盘事件,下面就一起来看看jquery是如何操作键盘事件的. 一.首先需要知道的是: 1.keydown() keydown事件会在键盘按下时触发. 2.keyup() k ...

  6. VBA开发经验总结之一:利用Range对象设计用户界面

    读罢<EXCEL专业开发>,最大的震撼就是著者对VBA技术的追求以及对Excel艺术品般的设计.受到此书著者的启发,也打算把自己在日常开发中一些经验总结出来,一来作为自己的知识储备,二来也 ...

  7. 不错的轮播插件flexslider

    http://flexslider.woothemes.com/ $('.flexslider').flexslider({ animation:'slide', //滑动效果:翻页效果,默认为fad ...

  8. 指令发email

    win7下指令发送email:(telnet:不为内部指令时控制面板 -> 程序和功能 -> 打开或关闭Windows功能,如下“telnet客户端”) telnet smtp.sina. ...

  9. SurfaceFlinger服务概述和学习计划

    SurfaceFlinger服务负责绘制Android应用程序的UI 实现相当复杂,要从正面分析它的实现不是一件容易的事.既然不能从正面分析,我们就想办法从侧面分析.说到底,无论SurfaceFlin ...

  10. iOS: 学习笔记, swift扩展

    // // YYExtension.swift // // Created by yao_yu on 14-7-18. // Copyright (c) 2014年 yao_yu. All right ...