Codevs_1040_[NOIP2001]_统计单词个数_(划分型动态规划)
描述
http://codevs.cn/problem/1040/
与Codevs_1017_乘积最大很像,都是划分型dp.
给出一个字符串和几个单词,要求将字符串划分成k段,在每一段中求共有多少单词(两个单词不能共享第一个字母),将每一段中的单词个数相加,求最大值.
1040 统计单词个数
2001年NOIP全国联赛提高组
给出一个长度不超过200的由小写英文字母组成的字母串(约定;该字串以每行20个字母的方式输入,且保证每行一 定为20个)。要求将此字母串分成k份(1<k<=40),且每份中包含的单词个数加起来总数最大(每份中包含的单词可以部分重叠。当选用一 个单词之后,其第一个字母不能再用。例如字符串this中可包含this和is,选用this之后就不能包含th)(管理员注:这里的不能再用指的是位 置,不是字母本身。比如thisis可以算做包含2个is)。
单词在给出的一个不超过6个单词的字典中。
要求输出最大的个数。
输入描述
Input Description
第一行为一个正整数(0<n<=5)表示有n组测试数据
每组的第一行有二个正整数(p,k)
p表示字串的行数;
k表示分为k个部分。
接下来的p行,每行均有20个字符。
再接下来有一个正整数s,表示字典中单词个数。(1<=s<=6)
接下来的s行,每行均有一个单词。
输出描述
Output Description
每行一个整数,分别对应每组测试数据的相应结果。
样例输入
Sample Input
1
1 3
thisisabookyouareaoh
4
is
a
ok
sab
样例输出
Sample Output
7
分析
用dp[i][k]表示将前i个字符划分成k段时的最优解(与乘积最大类似),那么有转移方程:
dp[i][k]=dp[j][k-1]+([j+1,i]中的单词个数).
这样就需要预处理每一个区间[i,j]中的单词个数.
对于区间[i,j],如果以str[i]开头有单词匹配,那么a[i][j]=a[i+1][j]+1. 否则a[i][j]=a[i+1][j].
写一个match函数来判断就好了.
注意:
1.codevs上的数据好像有点问题,注意读入.
#include <bits/stdc++.h>
using namespace std; const int maxl=+,maxk=+,maxd=;
int n,p,K,s,len;
int a[maxl][maxl],dp[maxl][maxl];
char str[maxl],dic[maxd][maxl]; bool match(int l,int r){
for(int i=;i<=s;i++){
int len=strlen(dic[i]+);
if(len>r-l+) continue;
bool flag=true;
for(int j=;j<=len;j++)
if(str[l-+j]!=dic[i][j]) {
flag=false;
break;
}
if(flag) return true;
}
return false;
}
void pre(){
memset(a,,sizeof a);
for(int i=;i<=len;i++){
if(match(i,i)) a[i][i]=;
for(int j=i-;j;j--){
if(match(j,i)) a[j][i]=a[j+][i]+;
else a[j][i]=a[j+][i];
}
}
}
void solve(){
pre();
for(int i=;i<=len;i++) dp[i][]=a[][i];
for(int k=;k<=K;k++)
for(int i=k;i<=len;i++)
for(int j=k-;j<i;j++)
dp[i][k]=max(dp[i][k],dp[j][k-]+a[j+][i]);
printf("%d\n",dp[len][K]);
}
void init(){
scanf("%d%d\n",&p,&K);
int id=;
for(int i=;i<=p;i++){
char c; c=getchar();
while(c>='a'&&c<='z'){
str[++id]=c;
c=getchar();
}
}
len=id;
scanf("%d",&s);
for(int i=;i<=s;i++) scanf("%s",dic[i]+);
}
int main(){
freopen("tjdcgs.in","r",stdin);
freopen("tjdcgs.out","w",stdout);
scanf("%d",&n);
while(n--){
init();
solve();
}
return ;
}
Codevs_1040_[NOIP2001]_统计单词个数_(划分型动态规划)的更多相关文章
- 【洛谷1026】【NOIP2001】统计单词个数
题面 题目描述 给出一个长度不超过200的由小写英文字母组成的字母串(约定;该字串以每行20个字母的方式输入,且保证每行一定为20个).要求将此字母串分成k份(1<k<=40),且每份中包 ...
- NOIP2001 统计单词个数
题三 统计单词个数(30分) 问题描述 给出一个长度不超过200的由小写英文字母组成的字母串(约定;该字串以每行20个字母的方式输入,且保证每行一定为20个).要求将此字母串分成k份(1<k&l ...
- codevs1040统计单词个数(区间+划分型dp)
1040 统计单词个数 2001年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 给出一个长度不超 ...
- 第六章 第一个Linux驱动程序:统计单词个数
现在进入了实战阶段,使用统计单词个数的实例让我们了解开发和测试Linux驱动程序的完整过程.第一个Linux驱动程序是统计单词个数. 这个Linux驱动程序没有访问硬件,而是利用设备文件作为介质与应用 ...
- 第六章第一个linux个程序:统计单词个数
第六章第一个linux个程序:统计单词个数 从本章就开始激动人心的时刻——实战,去慢慢揭开linux神秘的面纱.本章的实例是统计一片文章或者一段文字中的单词个数. 第 1 步:建立 Linu x 驱 ...
- NOIP200107统计单词个数
NOIP200107统计单词个数 难度级别: A: 编程语言:不限:运行时间限制:1000ms: 运行空间限制:51200KB: 代码长度限制:2000000B 试题描述 给出一个长度不超过200的由 ...
- luogu P1026 统计单词个数
题目链接 luogu P1026 统计单词个数 题解 贪心的预处理母本串从i到j的最大单词数 然后dp[i][j] 表示从前i个切了k次最优解 转移显然 代码 #include<cstdio&g ...
- Codevs 1040 统计单词个数
1040 统计单词个数 2001年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 给出一个长度不超过200的 ...
- P1026 统计单词个数——substr
P1026 统计单词个数 string 基本操作: substr(x,y) x是起始位置,y是长度: 返回的是这一段字符串: 先预处理sum[i][j],表示以i开头,最多的单词数: 从后往前寻找,保 ...
随机推荐
- Android XML解析
解析XML有三种方式:Dom.SAX.Pull 其中pull解析器运行方式与SAX类似. 我们首先认识pull解析器:http://developer.android.com/intl/zh-cn/r ...
- C# 的static与单例模式
C# 的static与单例模式 static是静态对象,在类被第一次使用,或者第一次被实例化时执行 /// <summary> /// 线程安全的单件模式 /// </summary ...
- jsf taglib定义函数
创建文件 在文件中添加function标签 <function> <function-name>getFileContent</function-name> & ...
- HDU 1175 连连看(BFS)
连连看 Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submi ...
- UVA 12097 LA 3635 Pie(二分法)
Pie My birthday is coming up and traditionally I'm serving pie. Not just one pie, no, I have a numbe ...
- PAT_1026 程序运行时间
问题描述: 要获得一个C语言程序的运行时间,常用的方法是调用头文件time.h,其中提供了clock()函数,可以捕捉从程序开始运行到clock()被调用时所耗费的时间.这个时间单位是clock ti ...
- 暑假集训(2)第九弹 ----- Points on Cycle(hdu1700)
Points on Cycle Time Limit:1000MS Memory Limit:32768 ...
- 快速排序 javascript实现
Quicksort(快速排序) 是由 东尼·霍尔 所发展的一种排序. 它比其他的Ο(n log n)算法更快, 因为它的内部循环(inner loop)可以在大部分的架构上很有效率地被实现出来.当然, ...
- Win7下Boost库的安装
Boost库是C++领域公认的经过千锤百炼的知名C++类库,涉及编程中的方方面面,简单记录一下使用时的安装过程 1.boost库的下载 boost库官网主页:www.boost.org 2.安装 将下 ...
- CentOs install oracle instant client
rpm -ivh oracle-instantclient11.2-basic-11.2.0.3.0-1.x86_64.rpm rpm -ivh oracle-instantclient11.2-de ...