Codeforces Round # 635 (Div. 2) E. Kaavi and Magic Spell interval dp

https://codeforces.ml/contest/1337/problem/E

Given two strings s and t, the length of the string s is greater than or equal to the length of t, and an empty string A;

Two operations can be performed:

1. Delete the first character of s and add it to the front of the A string;

2. Delete the first character of s and add it to the end of the A string;

Find the prefix of A in this process equal to the number of t and mod998244353;

E.g:

s: abab

t: no

The result is 12

 

The A string is an empty string when it does not include a at the beginning, so there are two ways to add a. Before the empty string and after the empty string, the answer is 6 * 2 = 12. (I did n’t understand this at first, the case is wrong ,,, dog head)

Idea: Treat the t string as a string of length n, the characters between (m, n) are arbitrary, first fix the first m strings of the A string, calculate the case of the first m strings, and the characters behind random;

The interval dp, dp [l] [r] represents the number of strings that match the characters in the interval [l, r] of A and t, first enumerate s [i], i is also the interval length, the length starts from 1, After matching the string with a length of 1, and then matching the string with a length of 2, then when we match a string with a length of 3, we only need to determine one character, and two of the characters have already been matched. When we When adding a new character, compare whether the current character is equal to the tl character and the tr character respectively.

dp equation:

When s [i] == t [l] or l> m: dp [l] [r] = (dp [l] [r] + dp [l + 1] [r])% mod;

When s [i] == t [r] or r> m: dp [l] [r] = (dp [l] [r] + dp [l] [r-1])% mod;

The sum of the values ​​of dp [1] [m ~ n] is the answer.

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN=3e3+5;
const ll mod=998244353;
const int inf=0x3f3f3f3f;
const long long INF=0x3f3f3f3f3f3f3f3f;
char s[MAXN],t[MAXN];
ll dp[MAXN][MAXN];
int main()
{
    scanf("%s%s",s+1,t+1);
    int n=strlen(s+1 );
     int m = strlen (t + 1 );
     for ( int i = 1 ; i <= n + 1 ; i ++) dp [i] [i- 1 ] = 1 ;
     for ( int i = 1 ; i <= n ; i ++) // enumeration string s + interval length 
    {
         for ( int l = 1 , r = l + i- 1 ; r <= n; l ++, r ++) // enumeration interval [l, r] 
        {
             if (s [i] == t [l] || l> m) dp [l] [r] = (dp [l] [r] + dp [l + 1 ] [r])% mod;
             if(s[i]==t[r]||r>m)dp[l][r]=(dp[l][r]+dp[l][r-1])%mod;
        }
    }
    ll ans=0;
    for(int i=m;i<=n;i++)ans=(ans+dp[1][i])%mod;
    printf("%lld\n",ans);
    return 0;
}
View Code

 

Guess you like

Origin www.cnblogs.com/MZRONG/p/12732176.html