Kaavi and Magic Spell(区间dp)

题目
参考
题意:给定s串和t串,长度分别为n和m(m<=n<=3000);每次取出s串并添加到A串(初始为空串),可以添加在头部,也可以添加在尾部。最多可以操作n次,问可以构造多少个A串,使得其前缀包含t串。
思路:区间dp。定义 d p [ i ] [ j ] dp[i][j] dp[i][j]表示包含子串 t [ i . . j ] t[i..j] t[i..j]的可达方案数,答案为 d p [ 1 ] [ m ] + d p [ 1 ] [ m + 1 ] + . . + d p [ 1 ] [ n ] dp[1][m]+dp[1][m+1]+..+dp[1][n] dp[1][m]+dp[1][m+1]+..+dp[1][n]。转移时注意边界。
处理关键点:把s串和t串都看出长度为n的串。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int mod = 998244353;
const int maxn = 3010;

char s[maxn],t[maxn];
int n,m; 
ll dp[maxn][maxn];

int main() {
	scanf("%s%s",s+1,t+1);
	n = strlen(s+1);
	m = strlen(t+1);
	for(int i = 1;i <= m;++i)
		if(t[i] == s[1])
			dp[i][i] = 2;
	for(int i = m+1;i <= n;++i)
		dp[i][i] = 2;//越界特判 
	for(int len = 2;len <= n;++len) {
		char ch = s[len];
		for(int l = 1,r;l+len-1 <= n;++l) {
			r = l+len-1;
			if(l > m || ch == t[l])
				dp[l][r] = (dp[l][r]+dp[l+1][r])%mod;
			if(r > m || ch == t[r])
				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);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值