2021-08-11 SSL 模拟赛 T2
依旧还是没有标题
题目大意:
给你两个字符串,让你求出它们的最长回文公共子序列。
思路:
我们看到 m<=20,那么我们可以用深搜弄出 B 串的所有子序列,然后判断它们是不是回文的,如果是的话就把它放到 A 串中去匹配,匹配成功即为一个合法答案。
时间复杂度
O
(
2
m
+
2
m
/
2
∗
n
)
O(2^m+2^{m/2}*n)
O(2m+2m/2∗n) ,在超时边缘疯狂徘徊。
听说有一个叫做什么子序列自动机的东西可以让时间复杂度优化到 O ( 2 m + 2 m / 2 ∗ m ) O(2^m+2^{m/2}*m) O(2m+2m/2∗m),当然因为我太菜,不会。
代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<cstring>
#include<vector>
#define r register
#define rep(i,x,y) for(r ll i=x;i<=y;++i)
#define per(i,x,y) for(r ll i=x;i>=y;--i)
using namespace std;
typedef long long ll;
const ll V=1e5+10;
string n,m;
ll x,y,ans;
bool check(string s)
{
ll len=s.length() ;
for(r ll i=0,j=len-1;i<j;i++,j--)
if(s[i]!=s[j]) return 0;
ll top=0;
rep(i,0,x-1)
{
if(n[i]==s[top]) ++top;
if(top>=len) return 1;
}
return 0;
}
void dfs(ll k,string s)
{
if(k>=y)
{
if(check(s)) ans=max(ans,(ll)s.length() );
return ;
}
dfs(k+1,s);
dfs(k+1,s+m[k]);
}
int main()
{
cin>>n>>m;
x=n.length() ,y=m.length() ;
dfs(0,"");
printf("%lld",ans);
return 0;
}