• Codeforces 808G Anthem of Berland


    题目传送门

      传送点I

      传送点II

      传送点III

    题目大意

      给定一个字符串$s$,和一个字符串$t$,$t$只包含小写字母,$s$包含小写字母和通配符'?'。询问$t$可能在$s$中出现最多多少次。

      原来觉得挺神仙,现在觉得还好。

      显然用$g_{i}$表示在匹配到第$i$个字符,最多能匹配$t$的次数。

      现在讨论它的转移,需要考虑它和前一个匹配有没有重叠。

    1. 如果没有重叠,直接从$g_{i - |t|}$转移。
    2. 如果有重叠,上一个可能的匹配的结束位置显然是可以枚举的,通过跳$fail$就能找到。我们记一个$f_{i}$表示恰好最后一个匹配在$i$处结束时的最多匹配次数。然后就可以转移了。

    Code

     1 /**
     2  * Codeforces
     3  * Problem#808G
     4  * Accepted
     5  * Time: 46ms
     6  * Memory: 1400k
     7  */
     8 #include <bits/stdc++.h>
     9 using namespace std;
    10 typedef bool boolean;
    11 
    12 const int N = 1e5 + 5;
    13 
    14 int n, m;
    15 char S[N], T[N];
    16 
    17 inline void init() {
    18     scanf("%s%s", S + 1, T + 1);
    19     n = strlen(S + 1);
    20     m = strlen(T + 1);
    21 }
    22 
    23 int fail[N];
    24 void kmp() {
    25     fail[0] = fail[1] = 0;
    26     for (int i = 1, j; i <= m; i++) {
    27         j = fail[i];
    28         while (j && T[i + 1] != T[j + 1])
    29             j = fail[j];
    30         fail[i + 1] = ((T[i + 1] == T[j + 1]) ? (j + 1) : (0));
    31     }
    32 }
    33 
    34 boolean match(char *str) {
    35     for (int i = 1; i <= m; i++)
    36         if (str[i] != T[i] && str[i] != '?')
    37             return false;
    38     return true;
    39 }
    40 
    41 int f[N], g[N];    // f: maximum match times when ends at i, g: maximum match times when ends before i ant at i.
    42 inline void solve() {
    43     kmp();
    44     for (int i = m; i <= n; i++) {
    45         if (match(S + (i - m))) {
    46             f[i] = max(f[i], g[i - m] + 1);
    47             for (int j = fail[m]; j; j = fail[j])
    48                 f[i] = max(f[i], f[i - m + j] + 1);
    49         }
    50         g[i] = max(f[i], g[i - 1]);    
    51     }
    52     printf("%d
    ", g[n]);
    53 }
    54 
    55 int main() {
    56     init();
    57     solve();
    58     return 0;
    59 }
  • 相关阅读:
    switch语句
    switch语句
    if语句三种格式
    dowhile语句
    if语句三种格式
    if语句配对
    ansible
    linux系统中网站服务程序(web服务/httpd服务)
    ansible
    ansible
  • 原文地址:https://www.cnblogs.com/yyf0309/p/7240960.html
Copyright © 2020-2023  润新知