2021.8.9提高B组模拟1T1 最长公共回文子序列(dfs)

Posted SSL_LKJ

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2021.8.9提高B组模拟1T1 最长公共回文子序列(dfs)相关的知识,希望对你有一定的参考价值。

最长公共回文子序列

题目大意

YJC最近在学习字符串的有关知识。今天,他遇到了这么一个概念:最长公共回文子序列。一个序列S,如果S是回文的且分别是两个或多个已知序列的子序列,且是所有符合此条件序列中最长的,则 S 称为已知序列的最长公共回文子序列。YJC很聪明,他很快就学会了如何求最长公共回文子序列。他现在想把问题规模扩大一些,于是他提出了这么一个问题:给一个长度为n(1≤n≤100000)的字符串a和一个长度为m(1≤m≤20)的字符串b,求a和b的最长公共回文子序列的长度。YJC发现他不会做了,于是他来问你这个问题的答案。

输入样例

第一行包含一个字符串,表示字符串a。
第二行包含一个字符串,表示字符串b。

aaaba
aabba

输出样例

一行,包含一个整数,表示a和b的最长公共回文子序列的长度。

3

题目数据

对于50%的数据,满足1≤n≤100。
对于100%的数据,满足1≤n≤100000,1≤m≤20,字符串只包含小写字母。

提示

最长公共回文子序列是aaa,长度为3。最长公共子序列是aaba,但它不是回文的。

解题思路

dfs暴搜

创造c字符串在较短字符串中取数

判断c字符串是否回文

回文在较长字符串内查找是否存在c子串

存在判断是否为最大值

注:可以判断长短、交换,便于处理

AC代码

#include<iostream>
#include<cstdio>
using namespace std;
int lena,lenb,mmax;
string a,b;
char c[100005];
bool pd(int x)//判断是否回文
{
	for(int i=1,j=x;i<=x/2;i++,j--)
		if(c[i]!=c[j])
			return false;
	return true;
}
bool work(int x)//与较长字符串比较
{
	int o=1;
	for(int i=0;i<lena;i++)
	{
		if(c[o]==a[i])o++;
		if(o>x)return true;
	}
	return false;
}
void dfs(int len,int x)//取数创造c字符串
{
	if(pd(len))
	 	if(work(len))
	  		mmax=max(mmax,len);
	for(int i=x;i<lenb;i++)
	{
		c[len+1]=b[i];
		dfs(len+1,i+1);
	}
}
int main()
{
	freopen("lcps.in","r",stdin);
	freopen("lcps.out","w",stdout); 
	cin>>a;cin>>b;
	lena=a.size();lenb=b.size();
	if(lenb>lena)//交换
	{
		for(int i=0;i<lena;i++)c[i]=a[i];
		for(int i=0;i<lenb;i++)a[i]=b[i];
		for(int i=0;i<lena;i++)b[i]=c[i];
		swap(lena,lenb);
	}
	dfs(0,0);
	printf("%d",mmax); 
	return 0;
}

谢谢

以上是关于2021.8.9提高B组模拟1T1 最长公共回文子序列(dfs)的主要内容,如果未能解决你的问题,请参考以下文章

Jzoj 4889NOIP2016提高A组集训第14场11.12暴力贪心最长公共回文子序列

2021.7.12提高B组模拟1T3 最长公共子串(记忆化搜索)

2021.7.12提高B组模拟1T1 好元素(hash)

2021.8.9提高B组模拟1T3 平均数(二分)(贪心)

2021.8.9提高B组模拟1T3 平均数(二分)(贪心)

最长连续公共子串最长公共子串(可以非连续)最长回文串(连续)最长回文串(可以不连续)最长递增数组的求解