题目描述

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

数据范围

对于50%的数据,满足1≤n≤100。

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

分析与演绎

原题所求:A和B的最长公共回文子串

花费O(2m∗m)来把原题转化为判断B是否是A的子串

暴力会需要O(n)的费用。

考虑交集优化:

由于A持续不变;

有些A中的字符在B中不用遍历甚至从未出现。

那么给A建立一个自动机:

具体而言,对于每一个位置,预处理出离他最近的’a’~’z’的位置。

那么每次遍历B,只需从A中的自动机跳对应字母就可以了。

代码

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#define ll long long
using namespace std;
const char* fin="lcps.in";
const char* fout="lcps.out";
const int inf=0x7fffffff;
const int maxn=100007,maxm=23;
int n,m,i,j,k;
char a[maxn],b[maxm],c[maxm];
int pos[maxn][26],last[26];
int judge(int v){
int i,j,k=0;
memset(c,0,sizeof(c));
for (i=1;i<=m;i++)
if (v&(1<<(i-1))) c[++k]=b[i];
for (i=1;i<=k/2;i++)
if (c[i]!=c[k-i+1]) return 0;
j=0;
for (i=1;i<=k;i++){
if (pos[j][c[i]-'a']) j=pos[j][c[i]-'a'];
else return 0;
}
return k;
}
int main(){
freopen(fin,"r",stdin);
freopen(fout,"w",stdout);
scanf("%s",a+1);
scanf("%s",b+1);
n=strlen(a+1);
m=strlen(b+1);
for (i=n;i>=0;i--){
for (j=0;j<26;j++){
pos[i][j]=last[j];
}
if (i) last[a[i]-'a']=i;
}
int ans=0;
for (i=(1<<m)-1;i>=0;i--) if (j=judge(i)) ans=max(j,ans);
printf("%d\n",ans);
return 0;
}

【JZOJ4889】【NOIP2016提高A组集训第14场11.12】最长公共回文子序列的更多相关文章

  1. 【JZOJ4888】【NOIP2016提高A组集训第14场11.12】最近公共祖先

    题目描述 YJC最近在学习树的有关知识.今天,他遇到了这么一个概念:最近公共祖先.对于有根树T的两个结点u.v,最近公共祖先LCA(T,u,v)表示一个结点x,满足x是u.v的祖先且x的深度尽可能大. ...

  2. 【NOIP2016提高A组集训第14场11.12】随机游走

    题目 YJC最近在学习图的有关知识.今天,他遇到了这么一个概念:随机游走.随机游走指每次从相邻的点中随机选一个走过去,重复这样的过程若干次.YJC很聪明,他很快就学会了怎么跑随机游走.为了检验自己是不 ...

  3. 【NOIP2016提高A组集训第14场11.12】随机游走——期望+树形DP

    好久没有写过题解了--现在感觉以前的题解弱爆了,还有这么多访问量-- 没有考虑别人的感受,没有放描述.代码,题解也写得歪歪扭扭. 并且我要强烈谴责某些写题解的代码不打注释的人,像天书那样,不是写给普通 ...

  4. 【JZOJ4890】【NOIP2016提高A组集训第14场11.12】随机游走

    题目描述 YJC最近在学习图的有关知识.今天,他遇到了这么一个概念:随机游走.随机游走指每次从相邻的点中随机选一个走过去,重复这样的过程若干次.YJC很聪明,他很快就学会了怎么跑随机游走.为了检验自己 ...

  5. JZOJ 【NOIP2016提高A组集训第16场11.15】兔子

    JZOJ [NOIP2016提高A组集训第16场11.15]兔子 题目 Description 在一片草原上有N个兔子窝,每个窝里住着一只兔子,有M条路径连接这些窝.更特殊地是,至多只有一个兔子窝有3 ...

  6. JZOJ 【NOIP2016提高A组集训第16场11.15】SJR的直线

    JZOJ [NOIP2016提高A组集训第16场11.15]SJR的直线 题目 Description Input Output Sample Input 6 0 1 0 -5 3 0 -5 -2 2 ...

  7. 【JZOJ4893】【NOIP2016提高A组集训第15场11.14】过河

    题目描述 数据范围 解法 由于同一个点,同一个圆盘最多只会走一次. 把(i,j)当作一个点,表示第i个点,放第i个圆盘. 那么就可以使用最短路. 时间复杂度为O(n4∗k). 事实上存在冗余圆盘,一个 ...

  8. 【NOIP2016提高A组集训第4场11.1】平衡的子集

    题目 夏令营有N个人,每个人的力气为M(i).请大家从这N个人中选出若干人,如果这些人可以分成两组且两组力气之和完全相等,则称为一个合法的选法,问有多少种合法的选法? 分析 如果暴力枚举每个人被分到哪 ...

  9. 【JZOJ4841】【NOIP2016提高A组集训第4场11.1】平衡的子集

    题目描述 夏令营有N个人,每个人的力气为M(i).请大家从这N个人中选出若干人,如果这些人可以分成两组且两组力气之和完全相等,则称为一个合法的选法,问有多少种合法的选法? 数据范围 40%的数据满足: ...

随机推荐

  1. fork 与 vfork

    fork 函数复制父进程(包括父进程的地址空间)产生子进程 在父进程返回子进程ID,在子进程本身返回0. fork一般有两个用处: 1.网络服务进程等待请求,新请求到来,fork一个子进程处理,父进程 ...

  2. Blow up the city

    Blow up the city 时间限制: 1 Sec  内存限制: 128 MB 题目描述 Country A and B are at war. Country A needs to organ ...

  3. C++11的for循环的新用法

    字符串 string str = "this is a string"; for(auto ch : str) cout << ch << endl; 等价 ...

  4. [转]深入理解定位父级offsetParent及偏移大小

    偏移量(offset dimension)是javascript中的一个重要的概念.涉及到偏移量的主要是offsetLeft.offsetTop.offsetHeight.offsetWidth这四个 ...

  5. iphone越狱开发之Class-Dump

    刚刚开始接触ios越狱开发,现在开始纪录每天的点滴进展 装载请注明 http://www.cnblogs.com/xiongwj0910/archive/2012/08/16/2642988.html ...

  6. spring cloud深入学习(六)-----熔断监控Hystrix Dashboard和Turbine

    Hystrix-dashboard是一款针对Hystrix进行实时监控的工具,通过Hystrix Dashboard我们可以在直观地看到各Hystrix Command的请求响应时间, 请求成功率等数 ...

  7. R语言中如何使用最小二乘法

    R语言中如何使用最小二乘法 这里只是介绍下R语言中如何使用最小二乘法解决一次函数的线性回归问题.         代码如下: > x<-c(6.19,2.51,7.29,7.01,5.7, ...

  8. jnhs-java实体类的有参构造器 无参构造器Could not instantiate bean class 实体类No default constructor found

    new一个对象的时候要用到构造函数, 例如Hello hello = new Hello();这时调用的是Hello的无参数构造方法; Hello hello = new Hello("hi ...

  9. webpack4进阶配置

    移动端CSS px自动转换成rem 需要两步来实现: px2rem-loader 在构建阶段将px转换成rem lib-flexible 页面渲染时动态计算根元素的font-size值(手机淘宝开源库 ...

  10. 2019.10.21 csp-s模拟测试81 反思总结

    T1: 把每一行状压,按行DP.设fi,j,k,i表示第几行,j是当前行的1覆盖状态,k是当前行选择按钮的状态.转移的时候枚举j和k,再枚举下一层的按钮选择情况l.如果l和j可以全覆盖当前层则转移合法 ...