Codeforces 808G Anthem of Berland【KMP】【DP】
简要题意
给你一个串s,上面有字母和一些通配符,问你将通配符换成字母之后最多可以出现多少次串t
首先有一个很傻子的做法就是\(dp_{i,j}\)表示s到第i个位置匹配t串前j个字符的完整t串个数
然后每次枚举前缀看看能不能转移。。。太不优秀了
那么就考虑这样做:
\(dp_{i}\)表示最后一个出现的完整的串t在第i个位置结尾的最大出现次数
\(maxv_{i}\)表示最后一个出现的完整的串t在第i个位置前结尾的最大出现次数
首先有一个转移是,如果当前位置被匹配,那么\(dp_{i} = maxv_{i - lent} + 1\)
或者我们就需要枚举当前串和上一个的公共长度
这样就相当于枚举t的一个是前缀又是后缀的东西
就很容易想到跳fail
然后就加上一个kmp板子就可以了
复杂度是\(|s|*|t|\)的
//Author: dream_maker
#include<bits/stdc++.h>
using namespace std;
//----------------------------------------------
//typename
typedef long long ll;
//convenient for
#define fu(a, b, c) for (int a = b; a <= c; ++a)
#define fd(a, b, c) for (int a = b; a >= c; --a)
#define fv(a, b) for (int a = 0; a < (signed)b.size(); ++a)
//inf of different typename
const int INF_of_int = 1e9;
const ll INF_of_ll = 1e18;
//fast read and write
template <typename T>
void Read(T &x) {
bool w = 1;x = 0;
char c = getchar();
while (!isdigit(c) && c != '-') c = getchar();
if (c == '-') w = 0, c = getchar();
while (isdigit(c)) {
x = (x<<1) + (x<<3) + c -'0';
c = getchar();
}
if (!w) x = -x;
}
template <typename T>
void Write(T x) {
if (x < 0) {
putchar('-');
x = -x;
}
if (x > 9) Write(x / 10);
putchar(x % 10 + '0');
}
//----------------------------------------------
const int N = 1e5 + 10;
char s[N], t[N];
int fail[N], dp[N], maxv[N];
void getfail(char *s) {
int lens = strlen(s + 1);
int j = 0; fail[1] = 0;
fu(i, 2, lens) {
while (j && s[j + 1] != s[i]) j = fail[j];
if (s[j + 1] == s[i]) ++j;
fail[i] = j;
}
}
bool match(char *s, int pos, char *t, int len) {
fu(i, 1, len)
if (s[pos + i -1] != t[i] && s[pos + i - 1] != '?') return 0;
return 1;
}
int main() {
#ifdef dream_maker
freopen("input.txt", "r", stdin);
#endif
scanf("%s%s", s + 1, t + 1);
getfail(t);
int lens = strlen(s + 1), lent = strlen(t + 1);
fu(i, lent, lens) {
if (match(s, i - lent + 1, t, lent)) {
dp[i] = max(dp[i], maxv[i - lent] + 1);
int j = fail[lent];
while (j) {
dp[i] = max(dp[i], dp[i - (lent - j)] + 1);
j = fail[j];
}
maxv[i] = max(maxv[i], dp[i]);
}
maxv[i] = max(maxv[i], maxv[i - 1]);
}
Write(maxv[lens]);
return 0;
}
Codeforces 808G Anthem of Berland【KMP】【DP】的更多相关文章
- Codeforces 808G Anthem of Berland(KMP+基础DP)
题意 给定一个字符串 \(s\) ,一个字符串 \(t\) ,其中 \(s\) 包含小写字母和 "?" ,\(t\) 只包含小写字母,现在把 \(s\) 中的问号替换成任意的小写字 ...
- 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$中出现最多多少次. 原 ...
- 【单调队列优化dp】 分组
[单调队列优化dp] 分组 >>>>题目 [题目] 给定一行n个非负整数,现在你可以选择其中若干个数,但不能有连续k个数被选择.你的任务是使得选出的数字的和最大 [输入格式] ...
- BZOJ2090: [Poi2010]Monotonicity 2【线段树优化DP】
BZOJ2090: [Poi2010]Monotonicity 2[线段树优化DP] Description 给出N个正整数a[1..N],再给出K个关系符号(>.<或=)s[1..k]. ...
- 1415. [NOI2005]聪聪和可可【记忆化搜索DP】
Description Input 数据的第1行为两个整数N和E,以空格分隔,分别表示森林中的景点数和连接相邻景点的路的条数. 第2行包含两个整数C和M,以空格分隔,分别表示初始时聪聪和可可所在的景点 ...
- 【KMP求最小周期】POJ2406-Power Strings
[题意] 给出一个字符串,求出最小周期. [思路] 对KMP的next数组的理解与运用orz ①证明:如果最小周期不等于它本身,则前缀和后缀必定有交叉. 如果没有交叉,以当前的next[n]为最小周期 ...
- POJ2406 Power Strings 【KMP 或 后缀数组】
电源串 时间限制: 3000MS 内存限制: 65536K 提交总数: 53037 接受: 22108 描述 给定两个字符串a和b,我们定义a * b是它们的连接.例如,如果a =" ...
- 【kmp+最小循环节】poj 2406 Power Strings
http://poj.org/problem?id=2406 [题意] 给定字符串s,s=a^n,a是s的子串,求n最大是多少 [思路] kmp中的next数组求最小循环节的应用 例如 ababab ...
随机推荐
- 这样获取celery的结果 有啥隐患没有啊?
- spring boot 登录认证
玩转spring boot——简单登录认证 https://www.cnblogs.com/GoodHelper/p/6343190.html 玩转spring boot——简单登录认证 https: ...
- java将配置信息写在数据库(利用反射)
Demo出处: 1. package com.fpx.pcs.prealert.process.xml.service.impl; public class CainiaoPushMessageSer ...
- ubuntu 14.04 解决apt-get update报错
apt-get update 报如下错误: 忽略 http://cn.archive.ubuntu.com trusty-backports/multiverse Translation-zh 忽略 ...
- mui 禁止透明背景点击关闭弹窗遮罩
//禁止关闭遮罩 window.addEventListener('tap', function(e) { e.target.className == 'mui-backdrop mui-active ...
- 新旧版ubuntu镜像免费下载
链接:https://pan.baidu.com/s/1hUNfiyA_Npj9QQ0vNLJ_Xw 密码:6k6i
- Java导出Excel(有数据库导出代码)
/** * 导出 * @param request * @param response * @throws Exception */ @SuppressWarnings("unchecked ...
- centos7 rabbitmq 安装
http://www.rabbitmq.com/install-rpm.html Overview rabbitmq-server is included in Fedora. However, th ...
- Find the odd int
Given an array, find the int that appears an odd number of times. There will always be only one inte ...
- bzoj2241
题解: 暴力枚举锤子大小 然后前缀和判断是否可行 代码: #include<bits/stdc++.h> #define N 105 using namespace std; int m, ...