LINK
Brief test instructions
Give you a string of S, with letters and some wildcard characters, asking you how many times you can see the wildcard character after you change it to a letter
First of all, a very foolish thing to do is \ (dp_{i,j}\) represents the number of complete T-strings that match the J-character before the T-string in the S-I position
Then every time I enumerate the prefixes to see if we can transfer ... It's not good.
Then consider doing this:
\ (dp_{i}\) indicates the maximum number of occurrences of the last occurrence of the complete string T at the end of the first I position
\ (maxv_{i}\) indicates the maximum number of occurrences of the last occurrence of the complete string T ending at the first position
First there is a transfer if the current position is matched, then \ (Dp_{i} = maxv_{i-lent} + 1\)
Or we need to enumerate the current string and the previous public length
This is the equivalent of enumerating t a prefix and suffix.
It's easy to think of a fail.
And then you can add a KMP board.
The complexity is \ (|s|*|t|\)
Author:dream_maker#include<bits/stdc++.h>using namespace std;//----------------------------------------- -----//typenametypedef 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 Typenamec onst int inf_of_int = 1e9;const ll inf_of_ll = 1e18;//fast Read and writetemplate <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 ge Tfail (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"