题目
题意
题意很简单,看洛谷就好了。
思路
拿到这题真是毫无头绪。
瞥了一眼题解代码——怎么这么短?难道这题并不难?然而再想了会儿,搞了几个错误的思路。最后还是得细看题解。不得不说,这状态设计确实巧妙,确实不知道是怎么想到的。那么直接讲题解的做法。
考虑 区间 d p \tt 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 [ l − r ] t[l-r] t[l−r] 的方案数。
对于 t i = = s 1 t_i==s_1 ti==s1,或者 i > l e n t i>lent i>lent, d p [ i ] [ i ] = 2 dp[i][i]=2 dp[i][i]=2
而:
我们考虑固定一个
l
l
l,枚举
L
e
n
Len
Len,那么
r
r
r 就为
l
+
L
e
n
−
1
l+Len-1
l+Len−1
- 如果 s L e n = = t l s_{Len}==t_l sLen==tl 或者 l > l e n t l >lent l>lent,那么 d p [ l ] [ r ] dp[l][r] dp[l][r] 可从 d p [ l + 1 ] [ r ] dp[l+1][r] dp[l+1][r] 转移来
- 如果 s L e n = = t r s_{Len}==t_r sLen==tr 或者 r > l e n t r > lent r>lent,那么 d p [ l ] [ r ] dp[l][r] dp[l][r] 可从 d p [ l ] [ r − 1 ] dp[l][r-1] dp[l][r−1] 转移来
Update
在蒋永神的引领下,我似乎知道了该题状态设计的大体思路。
我们考虑对于 S S S 串中的其他元素,并不能确定它在 T T T 中的位置。然而,只有 S S S 中的最后一个元素,我们知道它一定是 T T T 中的第一个或最后一个元素,那么这是我们就可以将其对应 T T T 匹配,并将 S S S 中前一位元素进行下一步转移。那么这就相当于是一个左右端点收拢的一个匹配问题,自然可以用 区间 d p \tt dp dp解决,而状态的设计也就迎刃而解了。
Code
#include <cstdio>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define MAXN 3005
#define Int register int
#define Mod 998244353
#define INF 0x3f3f3f3f3f3f3f3f
using namespace std;
inline LL Abs(LL x)
{
if (x > 0)
return x;
return - x;
}
inline LL Min(LL x,LL y)
{
return x < y ? x : y;
}
inline LL Max(LL x,LL y)
{
return x > y ? x : y;
}
inline void read(LL &x)
{
x = 0;
LL f = 1;
char s = getchar();
while (s < '0' || s > '9')
{
if (s == '-')
f = -1;
s = getchar();
}
while (s >= '0' && s <= '9')
{
x = (x << 3) + (x << 1) + (s ^ 48);
s = getchar();
}
x *= f;
}
char S[MAXN], T[MAXN];
LL dp[MAXN][MAXN];
int main()
{
scanf("%s", S + 1);
scanf("%s", T + 1);
LL Lens = strlen(S + 1);
LL Lent = strlen(T + 1);
for (Int i = 1; i <= Lens; ++ i)
if (S[1] == T[i] || i > Lent)
dp[i][i] = 2;
for (Int Len = 1; Len <= Lens; ++ Len)
for (Int l = 1; l + Len - 1 <= Lens; ++ l)
{
LL r = l + Len - 1;
if (r > Lent || S[Len] == T[r])
dp[l][r] += dp[l][r - 1], dp[l][r] %= Mod;
if (l > Lent || S[Len] == T[l])
dp[l][r] += dp[l + 1][r], dp[l][r] %= Mod;
}
LL Ans = 0;
for (Int i = Lent; i <= Lens; ++ i)
Ans += dp[1][i], Ans %= Mod;
printf("%lld", Ans);
return 0;
}