ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

字符串

2022-04-14 18:33:30  阅读:141  来源: 互联网

标签:le int ret Kri 字符串 删去


题目描述
Kri 非常喜欢字符串,所以他准备找 \(t\) 组字符串研究。

第 \(i\) 次研究中,Kri 准备了两个字符串 \(S\) 和\(R\) ,其中 \(S\) 长度为 \(n\),且只由 \(0, 1, -\) 三种字符构成(注:这里的第三种字符是减号),\(R\) 初始时为空。

每次研究,Zay 会带着一个美丽的长度为 \(m\) 的字符串 \(T\) 来找 Kri 玩,Kri 非常羡慕 Zay 拥有如此美丽的字符串,便也想用字符串 \(S\) 和 \(R\) 变出字符串 \(T\)。

具体地,Kri 将会进行 \(n\) 次操作。每次操作中,Kri 会取出 \(S\) 的第一个字符(记为 \(c\)),并将其从 \(S\) 中删去。如果 \(c = \texttt{-}\),则 Kri 要删去 \(R\) 的开头字符或结尾字符(数据保证删去后 \(R\) 不为空)。否则,Kri 会将 \(c\) 加入到 \(R\) 的末尾。

当进行完所有操作后,Kri 会检查 \(R\) 是否和 \(T\) 相等。如果 \(R=T\),Kri 就会感到开心;否则,Kri 会感到难受。

请问在每次研究中,Kri 有多少种操作方式使自己最后感到开心?我们定义两种方案不同,当且仅当在某种方案的某次操作中, Kri 删去了 \(R\) 的开头字符。而在另一种方案的这次操作中, Kri 删去了 \(R\) 的结尾字符。

由于答案可能很大,你只需要输出答案除以 \(1,000,000,007\)(即 \(10^9+7\))的余数。

输入格式
第一行一个正整数 tt。

接下来有 tt 组数据分别表示 tt 次字符串的研究,对于每组数据:

第一行有两个正整数 n,mn,m,分别表示字符串 S,TS,T 的长度。

第二行是字符串 SS。

第三行是字符串 TT。

输出格式
共 tt 行,第 ii 行表示第 ii 组研究的答案。

输入输出样例
输入 #1

3
6 2
10-01-
01
7 3
010-1-1
101
6 4
111-00
1100

输出 #1

2
1
2

输入 #2
见附件中的 string2.in
输出 #2
见附件中的 string2.out
说明/提示
【样例 1 解释】

对于第一组数据,有以下两种方案:

第一个 - 删 \(R\) 的开头,第二个 - 删 \(R\) 的结尾。
第一个 - 删 \(R\) 的结尾,第二个 - 删 \(R\) 的开头。
【数据范围】

对于 \(20\%\) 的数据,\(n,m\le 15\)。

对于 \(30\%\) 的数据,\(n,m\le 30\)。

对于 \(70\%\) 的数据,\(n,m\le 80\)。

对于另 \(10\%\) 的数据,保证答案不超过 \(1\)。

对于 \(100\%\) 的数据,\(1\le t\le 5\),\(1\le n,m\le 400\)。

每一个字符有几种可能。要不就是在前面被删去,要不就是在后面被删去,要不就是保持着不被删去。设现在有\(x\)个已匹配,\(y\)个在前面被删,\(z\)个在后面被删。然后做dp。我们来考虑在哪些情况下能执行那些操作。
首先如果现在遇到了一个减号,那么在前面的数只能在有可以删的数时才能删,后面的数同理。这个转移相对简单。
如果不是减号呢?首先如果我们要把它归为不被删去的数,就要把他与匹配串的下一位比较,如果一样才可以转移。同时必须后面没有要被删的数。
如果我们要把它归为在前面删的数,那么就要在既没有不被删的数也没有在后面删的数时,这个数才能在前面删。
如果我们把它归为在后面删的数,其实什么时候都可以。然后我们的dp就完成了。
当这个dp如果加上计算已经到达了哪一位这一维度,看似会超时,当其实,我们可以通过x,y,z算出到了哪一位置,把他们全部加起来就好了。

#include<cstdio>
#include<cstring>
const int N=405,P=1e9+7;
char c[N],s[N];
int t,n,m,f[N][N][N];
int dfs(int t,int x,int y,int z)
{
	if(t==n)
		return x==m;
	int ret=0;
	if(f[t][x][y]!=-1)
		return f[t][x][y];
	if(c[t]=='-')
	{
		if(y)
			ret+=dfs(t+1,x,y-1,z);
		if(z)
			ret+=dfs(t+1,x,y,z-1);
		return f[t][x][y]=ret%P;
	}
	if(c[t]==s[x]&&!z)
		ret=dfs(t+1,x+1,y,z);
	ret=(ret+dfs(t+1,x,y,z+1))%P;
	if(!x&&!z)
		ret=(ret+dfs(t+1,x,y+1,z))%P;
	return f[t][x][y]=ret;
}
int main()
{
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d%d%s%s",&n,&m,c,s);
		memset(f,-1,sizeof(f));
		printf("%d\n",dfs(0,0,0,0));
	}
}

标签:le,int,ret,Kri,字符串,删去
来源: https://www.cnblogs.com/mekoszc/p/16145996.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有