T3

题目描述

给出一个长度不超过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

说明

this/isabookyoua/reaoh

思路:

  我们可以用DP+KMP来处理这道题

  首先需要知道题目要求是:

      不能以同一个开头生成两个单词

  千万别理解错意思、、、

  由于在拆分字符串的过程中,如果以某位置为首某个较短单词被截断,那么以该位置为首的较长单词必然也会被截断。

    也就是说,对于各个位置来说我们选取较短的单词总不会比选取较长的单词所形成的单词少。

  那么题目就转化成了在每一个位置上选取能够形成的最短的单词,如果不能形成则为0,直接continue即可

  DP转移方程也是很好想的:

      if(dp[x][j-1])

        dp[i][j]=max(dp[i][j],dp[x][j-1]+KMP(x+1,i));//其中x是我们枚举的划分位置的前一个字符

坑点:

  注意题目要求的读入方式

上代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; const int L1 = ;
const int L2 = ;
int len;
char a[L1];
void init(int T) {
char c;
while(T--) {
for(int i=; i<; i++) {
scanf(" %c",&c);
a[len++]=c;
}
}
} char d[L2][L1]; //存字典
int sum,cnt;
//sum:统计一段单词中可以匹配的总个数
//cnt:字典单词总个数
int nxt[L2][L1],nowx[L2],dl[L2];
//nxt[]:开两维的原因是因为----不止一个模式串要跟文本串进行匹配
//nowx[]:每个单词当前在KMP函数中匹配的位数
//dl[]:字典中每个单词的长度
bool vis[L1]; //判重
int KMP(int l,int r) {
sum=;
memset(vis,false,sizeof(vis));
memset(nowx,,sizeof(nowx));
for(int i=l; i<=r; i++)
for(int j=; j<cnt; j++) {
while(nowx[j] && a[i]!=d[j][nowx[j]])
nowx[j]=nxt[j][nowx[j]];
if(a[i]==d[j][nowx[j]]) nowx[j]++;
if(nowx[j]==dl[j] && !vis[i-dl[j]+]) { //匹配成功
vis[i-dl[j]+]=true; //标记开头
sum++;
}
}
return sum;
} int dp[L1][L1];
int main() {
int p,k,x;
scanf("%d%d",&p,&k);
init(p);
scanf("%d",&cnt);
for(int i=; i<cnt; i++) {
scanf("%s",d[i]);
dl[i]=strlen(d[i]);
}
for(int i=; i<cnt; i++) {
x=;
nxt[i][x]=nxt[i][x+]=;
for(int j=; j<dl[i]; j++) {
while(x && d[i][x]!=d[i][j]) x=nxt[i][x];
nxt[i][j+]=d[i][x] == d[i][j] ? ++x : ;
}
}
for(int i=; i<len; i++) {
for(int j=; j<=k; j++) {
if(j==) dp[i][j]=KMP(,i);
else {
for(x=; x<i; x++)
if(dp[x][j-])
dp[i][j]=max(dp[i][j],dp[x][j-]+KMP(x+,i));
}
}
}
printf("%d",dp[len-][k]);
return ;
}

Noip2001 提高组 T3的更多相关文章

  1. 洛谷 P1025 & [NOIP2001提高组] 数的划分(搜索剪枝)

    题目链接 https://www.luogu.org/problemnew/show/P1025 解题思路 一道简单的dfs题,但是需要剪枝,否则会TLE. 我们用dfs(a,u,num)来表示上一个 ...

  2. JZOJ2020年8月11日提高组T3 页

    JZOJ2020年8月11日提高组T3 页 题目 Description 战神阿瑞斯听说2008年在中华大地上,将举行一届规模盛大的奥林匹克运动会,心中顿觉异常兴奋,他想让天马在广阔的天空上,举行一场 ...

  3. 【GDKOI2014】JZOJ2020年8月13日提高组T3 壕壕的寒假作业

    [GDKOI2014]JZOJ2020年8月13日提高组T3 壕壕的寒假作业 题目 Description Input Output 输出n行.第i行输出两个整数,分别表示第i份作业最早完成的时刻以及 ...

  4. JZOJ2020年8月10日提高组T3 玩诈欺的小杉

    JZOJ2020年8月10日提高组T3 玩诈欺的小杉 题目 Description 是这样的,在小杉的面前有一个N行M列的棋盘,棋盘上有\(N*M\)个有黑白棋的棋子(一面为黑,一面为白),一开始都是 ...

  5. 【佛山市选2013】JZOJ2020年8月7日提高组T3 海明距离

    [佛山市选2013]JZOJ2020年8月7日提高组T3 海明距离 题目 描述 对于二进制串a,b,他们之间的海明距离是指两个串异或之后串中1的个数.异或的规则为: 0 XOR 0 = 0 1 XOR ...

  6. 【NOIP2015模拟11.5】JZOJ8月5日提高组T3 旅行

    [NOIP2015模拟11.5]JZOJ8月5日提高组T3 旅行 题目 若不存在第\(k\)短路径时,输出"Stupid Mike" 题解 题意 给出一个有\(n\)个点的树 问这 ...

  7. [NOIP2001提高组]CODEVS1014 Car的旅行路线(最短路)

    最短路,这个不难想,但是要为它加边就有点麻烦..还好写完就过了(虽然WA了一次,因为我调试用的输出没删了..),不然实在是觉得挺难调的.. ------------------------------ ...

  8. 【NOIP2013提高组T3】加分二叉树

    题目描述 设一个n个节点的二叉树tree的中序遍历为(1,2,3,…,n),其中数字1,2,3,…,n为节点编号.每个节点都有一个分数(均为正整数),记第i个节点的分数为di,tree及它的每个子树都 ...

  9. noip1998 提高组t3 挖地雷

    题目背景 NOIp1996提高组第三题 题目描述 在一个地图上有N个地窖(N<=20),每个地窖中埋有一定数量的地雷.同时,给出地窖之间的连接路径.当地窖及其连接的数据给出之后,某人可以从任一处 ...

随机推荐

  1. (转)从0移植uboot(三) _编译最小可用uboot

    ref: https://www.cnblogs.com/xiaojiang1025/p/6436752.html 前两篇介绍了uboot-2013.01的配置原理以及大体的运行流程,本文将讨论如何对 ...

  2. (二)Spring框架之JDBC的基本使用(p6spy插件的使用)

    案例一: 用Spring IOC方式使用JDBC Test_2.java package jdbc; import java.lang.Thread.State; import java.sql.Co ...

  3. Java Convention 公约数计算

    Java Convention 公约数计算 /** * <html> * <body> * <P> Copyright 1994-2018 JasonInterna ...

  4. ES6语法 学习

    ECMAScript 6,也被称为ECMAScript 2015是ECMAScript标准的最新版本.6是语言的一个重要更新,并第一次更新语言由于ES5 2009标准.现在主要JavaScript引擎 ...

  5. c++-01--迭代器

    迭代器的概念 除了在其它语言中司空见惯的下标法访问容器元素之外,C++ 语言提供了一种全新的方法——迭代器(iterator)来访问容器的元素.迭代器其实类似于引用,指向容器中某一元素.迭代器(ite ...

  6. EF中DbContext的生命周期

    /// <summary>/// 依赖注入系统中类的生命周期./// </summary>public enum DependencyLifeStyle{    /// < ...

  7. 初学java1 数据类型

    java数据类型 分为8种 整型 byte 8位 short 16位 int 32位 long 64位 字符型 char 必需为单引号'' 且只能有一个字符 浮点型 float double 布尔类型 ...

  8. redis cluster异地数据迁移,扩容,缩容

    由于项目的服务器分布在重庆,上海,台北,休斯顿,所以需要做异地容灾需求.当前的mysql,redis cluster,elastic search都在重庆的如果重庆停电了,整个应用都不能用了. 现在考 ...

  9. python多线程与多进程异步事件框架

    多线程简单实现 #!/usr/bin/env python # -*- coding: UTF-8 -*- import logging import queue import threading f ...

  10. 一步一步教你实现iOS音频频谱动画(二)

    如果你想先看看最终效果再决定看不看文章 -> bilibili 示例代码下载 第一篇:一步一步教你实现iOS音频频谱动画(一) 本文是系列文章中的第二篇,上篇讲述了音频播放和频谱数据计算,本篇讲 ...