首页 > 其他分享 >每日一题-合并回文子串

每日一题-合并回文子串

时间:2023-04-25 17:46:06浏览次数:51  
标签:子串 int dg memset bool ans 一题 回文 fo

合并回文子串
由于n比较小,我们可以区间dp
\(f[i][j][a][b]\)表示s[i,j]和t[a,b]能否一起构成回文子串。
\(g[i][j],h[i][j]\)分别表示s[i,j],t[i,j]能否构成回文字串。

g,h直接暴力求即可。
注意判断边界条件,也就是i=j和a=b的情况

#include<cstdio>
#include<algorithm>
#include<cstring>
#define fo(i,a,b) for (int (i)=(a);(i)<=(b);(i)++)
#define fd(i,b,a) for (int (i)=(b);(i)>=(a);(i)--)
#define A puts("Alice")
#define B puts("Bob")
using namespace std;
typedef long long ll;
const ll mo=998244353;
const int N=55;
char s[N],t[N];
int n,m,ans;
bool f[N][N][N][N],g[N][N],h[N][N];
bool v[N][N][N][N];
bool judge(int l,int r,int op){
	if (!op) {
		while (l<r){
			if (s[l]!=s[r]) return 0;
			l++; r--;
		}
		return 1;
	}
	else{
		while (l<r){
			if (t[l]!=t[r]) return 0;
			l++; r--;
		}
		return 1;
	}
}
void dg(int x,int y,int a,int b){
	if (v[x][y][a][b]) return;
	v[x][y][a][b]=1;
	
	if (x==y && a==b) {
		f[x][y][a][b]=(s[x]==t[a]);
		return;
	}
	if (x>y) {
		f[x][y][a][b]=h[a][b]; 
		return;
	}
	if (a>b) {
		f[x][y][a][b]=g[x][y]; 
		return;
	}
	bool z=0;
	
	if (s[x]==s[y] && x!=y) {
		dg(x+1,y-1,a,b); 
		z|=f[x+1][y-1][a][b];
	}
	if (s[x]==t[b]) {
		dg(x+1,y,a,b-1);
		z|=f[x+1][y][a][b-1];
	}
	if (t[a]==t[b] && a!=b) {
		dg(x,y,a+1,b-1);
		z|=f[x][y][a+1][b-1];
	}
	if (t[a]==s[y]){
		dg(x,y-1,a+1,b);
		z|=f[x][y-1][a+1][b];
	}
	f[x][y][a][b]=z;
}
int main(){
//	freopen("data.in","r",stdin);
//	freopen("data.out","w",stdout);
	int T;
	scanf("%d",&T);
	while (T--){
		scanf("%s",s+1);
		n=strlen(s+1);

		scanf("%s",t+1);
		m=strlen(t+1);
		
		memset(f,0,sizeof(f));
		memset(g,0,sizeof(g));
		memset(h,0,sizeof(h));
		memset(v,0,sizeof(v));
	
		fo(i,1,n) fo(j,i,n) g[i][j]=judge(i,j,0);
		fo(i,1,m) fo(j,i,m) h[i][j]=judge(i,j,1);
		
		ans=0;
		fo(i,1,n) fo(j,i,n) fo(k,1,m) fo(l,k,m) {
			dg(i,j,k,l);
			if (f[i][j][k][l]) ans=max(ans,(l-k+1 +j-i+1));
		}
		printf("%d\n",ans);
	}
	return 0;
}  

标签:子串,int,dg,memset,bool,ans,一题,回文,fo
From: https://www.cnblogs.com/ganking/p/17353358.html

相关文章

  • LeetCode 131.分割回文串
    1.题目:给你一个字符串s,请你将s分割成一些子串,使每个子串都是回文串。返回s所有可能的分割方案。回文串是正着读和反着读都一样的字符串。示例1:输入:s="aab"输出:[["a","a","b"],["aa","b"]]示例2:输入:s="a"输出:[["a"]]来源:力扣(LeetCode)链接:https......
  • [Week 18] 每日一题(C++,动态规划,线段树,数学)
    目录[Daimayuan]T1最长公共子序列(C++,DP,二分)输入格式输出格式数据范围输入样例输出样例解题思路[Daimayuan]T2喵喵序列(C++,序偶)题目描述输入格式输出格式样例输入样例输出样例说明数据范围双倍经验解题思路:[Daimayuan]T3漂亮数(C++,字符串)输入描述输出描述输入样例输出样例解题......
  • 1163. 按字典序排在最后的子串
    题目链接:1163.按字典序排在最后的子串方法:双指针解题思路【正常走路我不走,就是跳,就是玩】任何非后缀子串字典序都小于其相应的后缀子串,如\(s[i,i+k]<s[i,n-1]\),\(k<n-1\),故答案一定为后缀子串,即\(s[i,n-1]\);观察数据规模,\(4*10^5\),暴力一定超时;法宝:......
  • 获取回文(数字篇)
    所谓回文数是指正着数和倒着数一样大,比如1001,5005,8228,9999。请打印出1000-9999之间所有的回文数代码如下: 结果如下:  logo ......
  • 每天一题
    在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。例如下面的二维数组就是每行、每列都递增排序。如果在这个数组中查找数字7,则返回true......
  • 实验一题目
    实验一数据库和表的建立、数据操作一、实验目的:掌握使用SQL语言进行数据定义和数据操纵的方法。二、实验要求:建立一个数据库stumanage,建立三个关系表student,course,sc。向表中插入数据,然后对数据进行删除、修改等操作,对关系、数据库进行删除操作。三、实验步骤:1、开始......
  • 【力扣-TS解题】1、回文数
    给你一个整数x,如果x是一个回文整数,返回true;否则,返回false。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。例如,121是回文,而123不是来源:力扣(LeetCode)转为字符串把数字转为字符串反转整个字符串对比两个字符串functionisPalindrome(x:number):b......
  • [牛客]链表的回文结构
    牛客链接思路:找中间结点从中间结点开始对后半段进行逆置比较前半段和后半段相等是,不相等不是只需将我们前面写过的链表中间结点,逆置链表的代码复用,并加上如下代码即可最终代码:/*structListNode{intval;structListNode*next;ListNode(intx):val(x),ne......
  • 马拉车(manacher) & 回文自动机(PAM)
    读了徐安矣2023年集训队论文写的,对于差分性质和习题,我会在理解清楚之后再补充。本篇博客仅讨论前两种算法。首先,马拉车和回文自动机都是处理回文串问题的。但在此之前,学习一些更加简单的回文算法。小trick:把给定串的两头和缝隙插入相同字符,且在边界处用不同字符标记,使得长度为......
  • 力扣——5.最长回文子串(c语言)
    题目描述:给定一个字符串s,找到s中最长的回文子串。你可以假设s的最大长度为1000。示例1:输入:"babad"输出:"bab"注意:"aba"也是一个有效答案。示例2:输入:"cbbd"输出:"bb"1、思路1:动态规划对于一个子串而言,如果它是回文子串,并且长度大于2,那么将它首尾两个字......