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暴力贪心最长公共回文子序列