CF1336C Kaavi and Magic Spell

一、题目

点此看题

二、解法

题目中的前缀放前放后提示我们可以用区间 d p dp 了(虽然我也看不太出来)

d p [ l ] [ r ] dp[l][r] S S 的前 r l + 1 r-l+1 项去填 T T [ l , r ] [l,r] (可能超过 m m ,但超过的话就随便填),转移就看 s [ r l + 1 ] s[r-l+1] 能不能填到 l l 位置上,能不能填在 r r 位置上。答案是 i = m n d p [ 1 ] [ i ] \sum_{i=m}^n dp[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);
}

猜你喜欢

转载自blog.csdn.net/C202044zxy/article/details/107632581