一、题目
二、解法
题目中的前缀
,放前放后
提示我们可以用区间
d
p
dp
dp了(虽然我也看不太出来)
设 d p [ l ] [ r ] dp[l][r] dp[l][r]为 S S S的前 r − l + 1 r-l+1 r−l+1项去填 T T T的 [ l , r ] [l,r] [l,r](可能超过 m m m,但超过的话就随便填),转移就看 s [ r − l + 1 ] s[r-l+1] s[r−l+1]能不能填到 l l l位置上,能不能填在 r r r位置上。答案是 ∑ i = m n d p [ 1 ] [ i ] \sum_{i=m}^n dp[1][i] ∑i=mndp[1][i]
#include <cstdio>
#include <cstring>
const int M = 3005;
const int MOD = 998244353;
int read()
{
int x=0,flag=1;char c;
while((c=getchar())<'0' || c>'9') if(c=='-') flag=-1;
while(c>='0' && c<='9') x=(x<<3)+(x<<1)+(c^48),c=getchar();
return x*flag;
}
int n,m,ans,dp[M][M];char s[M],t[M];
int main()
{
scanf("%s",s+1);n=strlen(s+1);
scanf("%s",t+1);m=strlen(t+1);
for(int i=1;i<=n;i++)
dp[i][i]=2*(i>m || s[1]==t[i]);
for(int i=n;i>=1;i--)
for(int j=i+1;j<=n;j++)
{
if(i>m || s[j-i+1]==t[i]) dp[i][j]=(dp[i][j]+dp[i+1][j])%MOD;
if(j>m || s[j-i+1]==t[j]) dp[i][j]=(dp[i][j]+dp[i][j-1])%MOD;
}
for(int i=m;i<=n;i++) ans=(ans+dp[1][i])%MOD;
printf("%d\n",ans);
}