CodeForces 808G Anthem of Berland 前缀函数 KMP DP
题意
第一行给我们一串长为s,只包含小写字母与问号的字符串A,第二行给我们一个长为t只有小写字母的字符串B, 同时满足 $ s * t \le 1e7 $
我们可以把问号变成任意的字母,我们需要求出如何变换才能使A串包含最多次B串(可以重叠),输出这个最大值
思路
单模式串匹配我们可以想到KMP算法或者前缀函数
一开始贪心考虑将“?”设置为100%匹配,但是显然这是行不通的,比如下面这组数据
acca
\]
显然答案是2,A应该变成如果kmp算法来贪心匹配,到第二个问号的时候,会将?设置为c,那么就和正确结果不符了
- 因为两字符串长度乘积最多为一千万,所以可以考虑DP,我们先预处理出B串的前缀函数值,然后给B串添加一个分隔符#之后,处理出前缀函数的自动机
\]
也就是在当前前缀函数值为i的情况下,下一个字符为j时转移到的前缀函数值。
- 这样我们设置DP数组
\]
为当前在A串的i位置,匹配到B串的j位置时(也就是前缀函数为j)的最大匹配数。为了便于理解我们初始化dp[0][0]为0,其他值为-1,转移方程为
\\
dp[i][prem[j][A[i]]] = max_{0 \le j \le t}\{dp[i - 1][j] + (prem[j][A[i]] == t)\} (A[i] \ne '?')
\]
- 最后取dp[s][i]中的最大值即可,对于空间问题,可以将两维写在一维中,或者使用滚动数组
AC代码
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 100000;
char ss[N + 5], sss[N + 5];
int prem[N + 5][26];
int pf[N + 5];
int dp[2][N + 5];
int len;
void prefun(char *s)
{
len = strlen(s + 1);
pf[0] = pf[1] = 0;
for (int i = 2; i <= len; ++i)
{
pf[i] = 0;
int l = pf[i - 1];
while (l && s[l + 1] != s[i])
{
l = pf[l];
}
if (s[l + 1] == s[i])
{
pf[i] = l + 1;
}
}
}
void preatm(char *s)
{
s[++len] = '#';
for (int i = 0; i < len; ++i)
{
for (int j = 0; j < 26; ++j)
{
if (i && 'a' + j != s[i + 1])
{
prem[i][j] = prem[pf[i]][j];
}
else
{
prem[i][j] = i + ('a' + j == s[i + 1]);
}
}
}
}
int main()
{
scanf("%s%s", ss + 1, sss + 1);
memset(dp, -1, sizeof(dp));
prefun(sss);
preatm(sss);
dp[0][0] = 0;
int len2 = strlen(ss + 1);
for (int i = 1; ss[i]; ++i)
{
if (ss[i] == '?')
{
for (int j = 0; j < len; ++j)
{
if (dp[1 - i % 2][j] != -1)
{
for (int k = 0; k < 26; ++k)
{
dp[i % 2][prem[j][k]] = max(dp[1 - i % 2][j] + (prem[j][k] == len - 1), dp[i % 2][prem[j][k]]);
}
}
}
}
else
{
for (int j = 0; j < len; ++j)
{
if (dp[1 - i % 2][j] != -1)
{
dp[i % 2][prem[j][ss[i] - 'a']] = max(dp[1 - i % 2][j] + (prem[j][ss[i] - 'a'] == len - 1), dp[i % 2][prem[j][ss[i] - 'a']]);
}
}
}
for (int j = 0; j < len; ++j)
{
dp[1 - i % 2][j] = -1;
}
}
int ans = 0;
for (int i = 0; i < len; ++i)
{
ans = max(ans, dp[len2 % 2][i]);
}
printf("%d\n", ans);
return 0;
}
CodeForces 808G Anthem of Berland 前缀函数 KMP DP的更多相关文章
- codeforces 808G Anthem of Berland
codeforces 808G Anthem of Berland 题面 给定\(s\)串和\(t\)串,字符集是小写字母.\(s\)串中有些位置的值不确定,要求你确定这些位置上的值,使得\(t\)在 ...
- Codeforces 808G Anthem of Berland - KMP - 动态规划
题目传送门 传送点I 传送点II 传送点III 题目大意 给定一个字符串$s$,和一个字符串$t$,$t$只包含小写字母,$s$包含小写字母和通配符'?'.询问$t$可能在$s$中出现最多多少次. 原 ...
- Codeforces 808G Anthem of Berland【KMP】【DP】
LINK 简要题意 给你一个串s,上面有字母和一些通配符,问你将通配符换成字母之后最多可以出现多少次串t 首先有一个很傻子的做法就是\(dp_{i,j}\)表示s到第i个位置匹配t串前j个字符的完整t ...
- Codeforces 808G Anthem of Berland(KMP+基础DP)
题意 给定一个字符串 \(s\) ,一个字符串 \(t\) ,其中 \(s\) 包含小写字母和 "?" ,\(t\) 只包含小写字母,现在把 \(s\) 中的问号替换成任意的小写字 ...
- 2021.08.30 前缀函数和KMP
2021.08.30 前缀函数和KMP KMP算法详解-彻底清楚了(转载+部分原创) - sofu6 - 博客园 (cnblogs.com) KMP算法next数组的一种理解思路 - 挠到头秃 - 博 ...
- 前缀函数与Z函数介绍
字符串算法果然玄学=_= 参考资料: OI Wiki:前缀函数与KMP算法 OI Wiki:Z函数(扩展KMP) 0. 约定 字符串的下标从 \(0\) 开始.\(|s|\) 表示字符串 \(s\) ...
- 转载 - kmp next函数 kmp的周期问题,深入了解kmp中next的原理
出处:http://www.cnblogs.com/wuyiqi/archive/2012/01/06/2314078.html kmp next函数 kmp的周期问题,深入了解kmp中next的原理 ...
- POJ 3336 Count the string (KMP+DP,好题)
参考连接: KMP+DP: http://www.cnblogs.com/yuelingzhi/archive/2011/08/03/2126346.html 另外给出一个没用dp做的:http:// ...
- 【KMP+DP】Count the string
KMP算法的综合练习 DP很久没写搞了半天才明白.本题结合Next[]的意义以及动态规划考察对KMP算法的掌握. Problem Description It is well known that A ...
- codeforces432D Prefixes and Suffixes(kmp+dp)
转载请注明出处: http://www.cnblogs.com/fraud/ ——by fraud D. Prefixes and Suffixes You have a strin ...
随机推荐
- Elasticsearch 6.8.6
mac;centos;unix; 下载 wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-6.8.6. ...
- TIM-有感BLDC转速解析
TIM-有感BLDC转速解析 1.基本概念解析 霍尔传感器的原理:通电线圈产生的磁场会使得转子所在位置会产生磁场,其中离得最近的霍尔传感器的磁场最强,进而导致最近霍尔传感器会产生最大的电压信号,这个最 ...
- [GXYCTF 2019]BabyUpload
看到题目是一个文件上传 就先随便传的东西试试,看有什么过滤之类的 上传一个一句话木马,提示后缀名不能为ph 随便上传了带有一句话木马的图片,发现上传成功,但这个图片不能直接利用,要先上传一个.htac ...
- 使用go语言开发hive导出工具
前言 新版 hive 提供了 beeline 工具,可以执行SQL并导出数据,不过操作还是有点复杂的,团队里有些同学不会Linux的基本操作,所以我花了亿点点时间写了个交互式的命令行工具方便使用. 效 ...
- 一个Node.js的小爬虫
爬虫其实就是对网页内特定id.class.标签内容的提取,多是循环出来的,对我们爬取非常便利. 1.安装node node官网下载安装包安装,后在命令行工具中输入node -v查看node安装的版本. ...
- CF1610B [Kalindrome Array]
Problem 题目简述 给你一个数列 \(a\),有这两种情况,这个数列是「可爱的」. 它本身就是回文的. 定义变量 \(x\),满足:序列 \(a\) 中所有值等于 \(x\) 的元素删除之后,它 ...
- MATLAB(Octave)命令记录
1. struct:结构体数组 aaaa_s.a = 1; aaaa_s.b = {'A','B','C'} aaaa_s.c = [1 2 3 4; 5 6 7 8]; save aaaa_s.tx ...
- JavaBean 之Hello World(入门实例)
本文主要参考<JavaEE企业应用实战>的例子,经过调试成功. 前言:如果多个jsp页面需要重复使用某段代码,我们可以把这段代码定义成Java类的方法,让后让多个jsp页面调用该方法即可, ...
- 「保姆级」网络爬虫教程(二):教你下载文库中的PDF文档!
如何点赞再看,养成习惯.微信公众号搜索「Job Yan」关注这个爱发技术干货的 Coder.本文 GitHub https://github.com/JobYan/PythonPearls 已收录,还 ...
- 潜在威胁信息模型(PTIM)-Potential threats Information Modeling
前言 这只是一位学识浅薄博主的一个突然想法,还望各位专业领域的专家教授轻怼 潜在威胁信息模型 目前的想法是通过全城摄像头建立城市的潜在威胁信息模型,这个潜在威胁可以包括:天气灾害(冰雹.雾霾能见度等) ...