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

设计状态dp[i][j]表示T串Ti到Tj(区间i,j)匹配到的个数

由于T串比S串小,所以在区间(m,n)可以插入的字符串是任意的。

转移方程 if s[i] = t[l],dp[l][r] = dp[l][r] + dp[l+1][r]

               if  s[i] = t[r] ,dp[l][r] = dp[l][r]  + dp[l][r-1]

              if l>m || r>m  dp[l][r] = dp[l][r] + dp[l+1][r],dp[l][r] = dp[l][r]  + dp[l][r-1] 因为超过T串m长度的部分可以任意插入字符串

注意:预处理dp[i][i-1] = 1,表示插入空串的操作数初始时有1种。

AC代码:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int maxn = 1e5+5;
 5 const ll mod = 998244353;
 6 ll dp[3005][3005];
 7 char s[3005],t[3005];
 8 int main(){
 9     int n,m;
10     scanf("%s",s+1);
11     scanf("%s",t+1);
12     n = strlen(s+1),m = strlen(t+1);
13     for(int i = 1;i<=3004;i++) dp[i][i-1] = 1;
14     for(int i = 1;i<=n;i++){
15         for(int l = 1,r = l + i - 1;r<=n;l++,r++){
16             if(l>m || s[i] == t[l]) dp[l][r] = (dp[l+1][r] + dp[l][r])%mod;
17             if(r>m || s[i] == t[r]) dp[l][r] = (dp[l][r-1] + dp[l][r])%mod;
18         }
19     }
20     ll ans = 0;
21     for(int i = m;i<=n;i++) ans = (ans + dp[1][i])%mod;
22     printf("%lld\n",ans);
23     return 0;
24 }

猜你喜欢

转载自www.cnblogs.com/AaronChang/p/12718962.html