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 ...
随机推荐
- Chapter 6. Build Script Basics
Chapter 6. Build Script Basics 6.1. Projects and tasks Everything in Gradle sits on top of two basic ...
- 计算机的数值转化与网络的IP地址分类与地址划分
数值转换 数字系统由来 远古时代是没有数字系统非位置化数字系统: 罗马数字 (I-1.II-2.III-3.IV-4.V-5.VI-6.VII-7.VIII-8.IX-9.X-10) 位置话数字化系统 ...
- CentOS7调整分区大小
前言 部署CentOS7的时候分配的动态扩充虚拟磁盘,共1T大小,在安装Centos时默认分区,系统仅给/分配50G,而大量空间都挂载到/home下,最近CentOS7使用中发现空间已不足够,所以就想 ...
- ELK7.x环境部署
1.Elasticsearch (ES)配置: 部署配置ES,需要配置JDK环境,JDK是Java语言的软件开发工具包: 下载JAVA jdk源码包: wget https://mirrors.yan ...
- 游戏客户端开发中对MVC模式的思考
话说在前头,我分析MVC模式是为了确定自己要做的独立游戏的结构出来,并不适用于大型商业游戏的开发. MVC模式的概述 关于MVC模式,Model用于存储数据,View层用于显示数据,Controlle ...
- 以太坊和比特币区块链的异同(一些QA)
1.比特币区块链和以太坊区块链有何区别? 比特币区块链与以太坊在设计和功能上有显著的不同.下面是关于比特币的主要点: 没有智能合约功能(按照以太坊的定义):比特币是为了作为一个去中心化的数字货币而创建 ...
- 解决使用mitmprox抓包可以访问网页,但是使用python request 调用该网站接口报错问题
可能有几种原因导致这种情况.以下是一些常见的问题和可能的解决方法: 证书验证问题: 当你使用mitmproxy抓包时,它通常会生成自签名的SSL证书,以便进行中间人攻击检查.但在Python中使用re ...
- 搓一个Pythonic list
总所周知,Python语言当中的list是可以存储不同类型的元素的,对应到现代C++当中,可以用std::variant或者std::any实现类似的功能.而Python官方的实现当中用到了二级指 ...
- .Net8 Blazor 尝鲜
全栈 Web UI 随着 .NET 8 的发布,Blazor 已成为全堆栈 Web UI 框架,可用于开发在组件或页面级别呈现内容的应用,其中包含: 用于生成静态 HTML 的静态服务器呈现. 使用 ...
- “技能兴鲁”职业技能大赛-网络安全赛项-学生组初赛 Crypto WP
babyRSA 查看代码 from gmpy2 import * from Crypto.Util.number import * flag = 'flag{I\'m not gonna tell y ...