【kmp】【动态规划】CF808G Anthem of Berland

news/2024/6/16 10:04:23 标签: 算法, kmp, 动态规划

题意

给定含有问号和小写字母的串S,和一个含有小写字母的串T,将S中的?变成小写字母,问T最多可以在S中匹配多少次
∣ S ∣ ∗ ∣ T ∣ ≤ 1 0 7 |S|*|T|\le10^7 ST107

分析

f i f_i fi表示S匹配到前 i 位的最多匹配次数
如果 i − m + 1 i-m+1 im+1 i i i可能匹配上的话, f i = f i − m + 1 f_i=f_{i-m}+1 fi=fim+1

但是仅仅这样是不够的,因为 i − m + 1 i-m+1 im+1 i i i中,可能有串重叠放着,也能产生贡献,这就要求T串首位相等的部分,也就是kmp中的nxt

所以我们从T的末尾开始,每跳一次nxt更新一下答案即可

注意这里的 f f f没有规定最后一位一定匹配,所以要额外记录一个 g g g表示s[i]==t[m]的答案,转移用 g g g

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+5;
char s[maxn],t[maxn];
int n,m;
int nxt[maxn];
int f[maxn],g[maxn];
int main()
{
    freopen("a.in","r",stdin);
    freopen("a.out","w",stdout);
    scanf("%s%s",s+1,t+1);
    n=strlen(s+1); m=strlen(t+1);
    for(int i=2,j=0;i<=m;i++)
    {
        while(j && t[i]!=t[j+1]) j=nxt[j];
        if(t[j+1]==t[i]) j++;
        nxt[i]=j; 
    }
    for(int i=1;i<=n;i++)
    {
        f[i]=f[i-1];
        int flag=0;
        for(int j=1;j<=m;j++)
            if(s[i-j+1]!=t[m-j+1] && s[i-j+1]!='?')
            {
                flag=1;
                break;
            }
        if(flag) continue;
        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;
}

http://www.niftyadmin.cn/n/1297685.html

相关文章

【Trie】【扫描线】【树状数组】loj2742. 「JOI Open 2016」销售基因

题意 给定n个字符串&#xff0c;m次询问&#xff0c;每次给定两个字符串s1,s2&#xff0c;问有多少字符串既有s1前缀又有s2后缀 分析 给字符串按照字典序排序&#xff0c;建立字典树。翻转后再排序建立另一个字典树。那么每次询问就是分别走两个字典树的子树的交集。 排序后…

【回文自动机】【动态规划】P4762 [CERC2014]Virus synthesis

题意 给定一个空串&#xff0c;每次操作可以在开头/末尾加一个字符或者是给当前字符串翻转接在后面&#xff0c;问最少多少次操作可以得到目标字符串 分析 考虑最终的答案是一个回文串再开头末尾加上一些字符得到的 先建立自动机&#xff0c;设f[i]表示转移到树上i节点表示的…

【网络流】CF311E Biologist

题意 有一个长度为n的01串&#xff0c;将第i个位置变为另外一个数字的代价是vi​ 。有m个要求 每个要求的形式是 首先确定若干位置都要是0 或者1 然后给定这K 个位置&#xff0c;如果些位置上都满足要求 那么就可以得Wk​ 元 某些要求如果失败了还要倒着给g 元 问最终能够得到…

【莫比乌斯反演】【线性筛约数和】P3312 [SDOI2014]数表

题意 求∑i1n∑j1m[σ1(gcd⁡(i,j))≤a]σ1(gcd⁡(i,j))\sum_{i1}^n \sum_{j1}^m [\sigma_1(\gcd(i,j))\le a]\sigma_1(\gcd(i,j))∑i1n​∑j1m​[σ1​(gcd(i,j))≤a]σ1​(gcd(i,j)) 分析 代码 #include<bits/stdc.h> using namespace std; typedef long long ll; c…

【动态规划】P5289 [十二省联考 2019] 皮配

题意 较长&#xff0c;略 分析 算法一 首先&#xff0c;考虑k0的部分分&#xff0c;我们可以分别进行阵营和派系的选择&#xff0c;因为每个人都可以选择任意四个导师&#xff0c;所以阵营和派系的搭配是任意的&#xff0c;那么我们分别dp&#xff0c;然后把合法的方案乘起…

【动态规划】【线段树】P8051 [ZYOI Round1] Bird/鸟

分析 先不考虑瞬移功能&#xff0c;设fif_ifi​表示i位置上的最多的飞行次数&#xff0c;那么我们可以线通过单调栈预处理出来每个位置 i &#xff0c;左侧和右侧第一个比它高的位置&#xff0c;分别记为lp[i]和rp[i]&#xff0c;那么转移方程为fimax{fj1∣lp[i]≤j≤rp[i]}f_…

【点分治】【动态规划】ybtoj712. 连通计数

题意 分析 因为树的形态固定&#xff0c;我们可以把一个连通块记录在树上深度最浅的节点上&#xff0c;且一个连通块内这样的点有且只有一个&#xff0c;所以这种统计方式不重不漏 那么我们可以利用点分治&#xff0c;每次计算以分治中心作为连通块最高点的符合条件的连通块个…

【01trie】【启发式合并】P6072 『MdOI R1』Path

题意 每个点有点权&#xff0c;求两条没有交点的路径&#xff0c;使得两条路径的异或和的和最大 n≤3e4时限&#xff1a;3.5sn \le 3e4 \\ 时限&#xff1a;3.5sn≤3e4时限&#xff1a;3.5s 分析 给每个点求出in[i]out[i]in[i] \ out[i]in[i] out[i]表示子树内的最大异或路径…