描述


http://codevs.cn/problem/1040/

Codevs_1017_乘积最大很像,都是划分型dp.

给出一个字符串和几个单词,要求将字符串划分成k段,在每一段中求共有多少单词(两个单词不能共享第一个字母),将每一段中的单词个数相加,求最大值.

1040 统计单词个数

2001年NOIP全国联赛提高组

时间限制: 1 s
空间限制: 128000 KB
题目等级 : 黄金 Gold
题目描述 Description

给出一个长度不超过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]_统计单词个数_(划分型动态规划)的更多相关文章

  1. 【洛谷1026】【NOIP2001】统计单词个数

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

  2. NOIP2001 统计单词个数

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

  3. codevs1040统计单词个数(区间+划分型dp)

    1040 统计单词个数 2001年NOIP全国联赛提高组  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold   题目描述 Description 给出一个长度不超 ...

  4. 第六章 第一个Linux驱动程序:统计单词个数

    现在进入了实战阶段,使用统计单词个数的实例让我们了解开发和测试Linux驱动程序的完整过程.第一个Linux驱动程序是统计单词个数. 这个Linux驱动程序没有访问硬件,而是利用设备文件作为介质与应用 ...

  5. 第六章第一个linux个程序:统计单词个数

    第六章第一个linux个程序:统计单词个数 从本章就开始激动人心的时刻——实战,去慢慢揭开linux神秘的面纱.本章的实例是统计一片文章或者一段文字中的单词个数.  第 1 步:建立 Linu x 驱 ...

  6. NOIP200107统计单词个数

    NOIP200107统计单词个数 难度级别: A: 编程语言:不限:运行时间限制:1000ms: 运行空间限制:51200KB: 代码长度限制:2000000B 试题描述 给出一个长度不超过200的由 ...

  7. luogu P1026 统计单词个数

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

  8. Codevs 1040 统计单词个数

    1040 统计单词个数 2001年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 给出一个长度不超过200的 ...

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

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

随机推荐

  1. MVC小系列(八)【改变Areas的FindView顺序】

    MVC小系列(八)[改变Areas的FindView顺序] 一般项目比较大的话,会根据模块建立Areas,这样结构清晰,也有利于路由的部署, 1 Areas下有自己的_LayOut模板,而如果希望所有 ...

  2. TransactionScope事务

    一个错误的理解就是Complete()方法是提交事务的,这是错误的,事实上,它的作用的表示本事务完成,它一般放在try{}的结尾处,不用判断前台操作是否成功,如果不成功,它会自己回滚. #region ...

  3. tomcat启动正常,404. Eclipse没有正确部署工程项目

    http://blog.csdn.net/lynn_wgr/article/details/7751228 在eclipse中新建的Dynamic Web Project.写好代码后,选择Run on ...

  4. ios NSAssert趣谈

    Apple 官网介绍 NSAssert 的定义如下: #define NSAssert(condition, desc, ...) \ do { \ __PRAGMA_PUSH_NO_EXTRA_AR ...

  5. 解码一个加密的js文件

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

  6. 选择第n小的元素之python实现源码

    def partition(A, p, r): j = p+1 for i in range(p+1, r+1): if(A[i] < A[p]): tmp = A[i] A[i] = A[j] ...

  7. <s:iterator></s:iterator>循环指定输出,(status的方法使用)

    list集合中的实体的一个属性是另一个实体的集合(如下) public class PetInfo { private int petId; private String private Set< ...

  8. 利用Xlinix SDK 建立Linux程序以及对该程序进行调试

    一.创建Linux程序 1. 点击File > New > Application Project .并参照下图设置. 2. 输入工程名,并选择存储路径. 3. 选择所需的操作系统平台(O ...

  9. 通过shell脚本实现代码自动化部署

    通过shell脚本实现代码自动化部署 一.传统部署方式及优缺点 1.传统部署方式 (1)纯手工scp (2)纯手工登录git pull.svn update (3)纯手工xftp往上拉 (4)开发给打 ...

  10. 【DP_树形DP专题】题单总结

    转载自 http://blog.csdn.net/woshi250hua/article/details/7644959#t2 题单:http://vjudge.net/contest/123963# ...