首页 > 其他分享 >CF808G Anthem of Berland 解题报告

CF808G Anthem of Berland 解题报告

时间:2023-01-09 19:37:17浏览次数:47  
标签:匹配 Berland 小写字母 Anthem while getchar CF808G 问号

Description

给定 $s$ 串和 $t$ 串,其中 $s$ 串包含小写字母和问号,$t$ 串只包含小写字母。

假设共有 $k$ 个问号。

你需要给把每个问号变成一个小写字母,共有 $26^k$ 种可能。

对于每种可能,设 $t$ 匹配 $s$ 的次数为 $f_i$,请输出 $\max(f_i)$。

Solution

发现 $|s|* |t| \leq 10^7$, 显然可以对于 $s$ 的每个位置对 $t$ 进行暴力匹配。

于是这是个线性问题,考虑 dp。用 $f_i$ 表示 $t$ 在 $s$ 的前 $i$ 个位置出现的最大次数。

如果当前位置能够匹配,显然 $f_i$ 可以从 $f_{i-m}$ 转移。但这是不够的,因为 $t$ 是可以重叠放的,而且仅仅有一个 $f$ 数组是不够的,于是我们可以用 $g_i$ 表示第 $i$ 个位置一定选的最大匹配数。枚举 $t$ 的 border,每次更新 $g_i$ 即可。

CODE

#include<bits/stdc++.h>
using namespace std;
inline int read() {
    int x = 0, f = 1; char c = getchar();
    while (c < '0' || c > '9') {if (c == '-') f = -f; c = getchar();}
    while (c >= '0' && c <= '9') {x = (x << 3) + (x << 1) + (c ^ 48); c = getchar();}
    return x * f;
}
const int N = 1e5 + 10;
int n, m, f[N], g[N], nxt[N];
char s[N], t[N];
inline bool chk (int p) {
    if (p < m) return false;
    for (int i = 1; i <= m; ++ i)
        if (s[p-i+1] != t[m-i+1] && s[p-i+1] != '?') return false;
    return true;
}
int main () {
    scanf("%s", s + 1); scanf("%s", t + 1);
    n = strlen(s + 1); m = strlen(t + 1); nxt[1] = 0;
    for (int i = 2, j = 0; i <= m; ++ i) {
        while (j && t[i] != t[j+1]) j = nxt[j];
        if (t[i] == t[j+1]) ++ j; nxt[i] = j;
    }
    for (int i = 1; i <= n; ++ i) {
        f[i] = f[i-1];
        if (chk(i)) {
            g[i] = f[i-m] + 1;
            for (int j = nxt[m]; j; j = nxt[j]) g[i] = max(g[i], g[i-(m-j)] + 1);
            f[i] = max(f[i], g[i]);
        }
    }
    printf("%d\n", f[n]);
    return 0;
}
View Code

 

标签:匹配,Berland,小写字母,Anthem,while,getchar,CF808G,问号
From: https://www.cnblogs.com/CikL1099/p/17038324.html

相关文章

  • CF808G Anthem of Berland
    \(\mathcalLink\)大概知道两种DP方法。(\(n\logn\)做法太神了)方法一:设\(f_i\)表示\(t\)在\(s[1\cdotsi]\)最多出现次数。当最后一位不会被匹配时,答案为\(f_......
  • Codeforces 1 C. Ancient Berland Circus
    题意:二维平面中,给定三个点,这三个点是正多边形的三个顶点,求正多边形最小的面积。思路:两对点分别求中垂线,相交点是多边形外接圆的圆心,圆心有了半径和角度也就有了,之后求一......
  • CF1C Ancient Berland Circus
    给定\(3\)个点,求以这\(3\)个点为顶点的正多边形面积最小值。先以这张图为例,首先可以肯定圆的半径是确定的。根据秦九韶公式,有\(S_{\triangleABC}=\sqrt{p(p-a)(p......
  • CF808G Anthem of Berland
    给定\(s\)和\(t\),其中\(s\)中有\(k\)个?,求\(s\)补齐?后匹配\(t\)的最大次数。\(|s|\times|t|\leq10^7\)。先用一组数据\(HACK\)掉贪心做法:(贪心只......