分析

首先,可以发现,区间是可以合并滴。把区间按左端点排序,对于两个区间[l1,r1]、[l2,r2],当l1<=l2 and r1>=l2,那么,将它们合成一个新的区间[l1,r2]。当一个位置不属于任何一个区间时,它自己独立成为一个区间。

接着dp,保证区间是从小到大的。

f[i][j]表示在从Si个区间,和子串T[j~|T|]的最长公共子串。

转移,

定义g[i]表示Si个区间的长度

枚举子串T[jj+g[i]-1]**每一个位置,当枚举到**k**时,**T[jk]T[k]的个数大于Si个区间中T[k]的个数,那么就breakf[i][j]=k-j+1。如果f[i][j]等于g[i],那么,f[i][j]=f[i][j]+f[i+1][j+g[i]]

但是,最长公共子串的串首并不一定是区间的串首,所以从i-1开始,往前搜,方法同上,设搜到的长度是num,ans就是max(num+f[i][j])。

#include <cmath>
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <queue>
const int maxlongint=2147483647;
using namespace std;
int lens,lent,f[4110][4100],g[5000],sum[2100][30],st[2100],b[100002][3],n,m,tot,ans,sm[30];
char s[4100],t[4100];
void q(int l,int r)
{
int i=l,j=r,mid=b[(l+r)/2][1],e;
while(i<j)
{
while(b[i][1]<mid) i++;
while(b[j][1]>mid) j--;
if(i<=j)
{
e=b[i][1];
b[i][1]=b[j][1];
b[j][1]=e;
e=b[i][2];
b[i][2]=b[j][2];
b[j][2]=e;
i++;
j--;
}
}
if(i<r) q(i,r);
if(l<j) q(l,j);
}
int main()
{
scanf("%s\n%s\n",t,s);
lent=strlen(t);
lens=strlen(s);
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d%d",&b[i][1],&b[i][2]);
}
for(int i=0;i<=lens-1;i++)
{
b[++n][1]=b[n][2]=i;
}
q(1,n);
for(int i=1;i<=n;i++)
{
if(st[tot]+g[tot]-1<b[i][1])
{
st[++tot]=b[i][1];
g[tot]=b[i][2]-b[i][1]+1;
}
else
{
g[tot]=max(g[tot],b[i][2]-st[tot]+1);
}
}
for(int i=1;i<=tot;i++)
{
for(int j=st[i];j<=st[i]+g[i]-1;j++)
{
sum[i][s[j]-96]++;
}
sum[i][0]=maxlongint;
}
for(int i=tot;i>=1;i--)
{
for(int j=lent-1;j>=0;j--)
{
int bz=true,g1=0;
memset(sm,0,sizeof(sm));
for(int k=j;k-j+1<=g[i];k++)
{
if(t[k]==t[-1])
{ }
else
if(k<=lent-1 && ++sm[t[k]-96]<=sum[i][t[k]-96])
{
f[i][j]++;
}
else
{
bz=false;
break;
}
}
if(bz)
{
f[i][j]+=f[i+1][j+g[i]];
}
int num=0;
memset(sm,0,sizeof(sm));
for(int k=j-1;k+g[i-1]-1>=j;k--)
{
if(++sm[t[k]-96]<=sum[i-1][t[k]-96])
{
num++;
}
else
{
bz=false;
break;
}
}
if(f[i][j]+num>ans)
{
ans=f[i][j]+num;
}
}
}
printf("%d",ans);
}

【GDOI 2016 Day1】第二题 最长公共子串的更多相关文章

  1. SPOJ 1811 Longest Common Substring (后缀自动机第一题,求两个串的最长公共子串)

    题目大意: 给出两个长度小于等于25W的字符串,求它们的最长公共子串. 题目链接:http://www.spoj.com/problems/LCS/ 算法讨论: 二分+哈希, 后缀数组, 后缀自动机. ...

  2. 【python】Leetcode每日一题-最长公共子序列

    [python]Leetcode每日一题-最长公共子序列 [题目描述] 给定两个字符串 text1 和 text2,返回这两个字符串的最长 公共子序列 的长度.如果不存在 公共子序列 ,返回 0 . ...

  3. 后缀数组(模板题) - 求最长公共子串 - poj 2774 Long Long Message

    Language: Default Long Long Message Time Limit: 4000MS   Memory Limit: 131072K Total Submissions: 21 ...

  4. 每日一题-——最长公共子序列(LCS)与最长公共子串

    最长公共子序列(LCS) 思路: 代码: def LCS(string1,string2): len1 = len(string1) len2 = len(string2) res = [[0 for ...

  5. 求最长公共子串 Longest Common Subsequence

    最长公共子串 // Longest Common Subsequence 子串有别于子序列, 子串是连续的, 而子序列可以不连续 /*--------------------------------- ...

  6. CODE【VS】3160 最长公共子串 (后缀自动机)

    3160 最长公共子串 题目描述 Description 给出两个由小写字母组成的字符串,求它们的最长公共子串的长度. 输入描述 Input Description 读入两个字符串 输出描述 Outp ...

  7. 【spoj2774】最长公共子串

    题目描述: 给你两个字符串,求它们最长公共子串的长度,如果不存在公共子串则输出0. 样例输入: yeshowmuchiloveyoumydearmotherreallyicannotbelieveit ...

  8. 「双串最长公共子串」SP1811 LCS - Longest Common Substring

    知识点: SAM,SA,单调栈,Hash 原题面 Luogu 来自 poj 的双倍经验 简述 给定两字符串 \(S_1, S_2\),求它们的最长公共子串长度. \(|S_1|,|S_2|\le 2. ...

  9. 动态规划(一)——最长公共子序列和最长公共子串

    注: 最长公共子序列采用动态规划解决,由于子问题重叠,故采用数组缓存结果,保存最佳取值方向.输出结果时,则自顶向下建立二叉树,自底向上输出,则这过程中没有分叉路,结果唯一. 最长公共子串采用参考串方式 ...

随机推荐

  1. robotframework之用户关键字的用法

    robotframework是一个关键字驱动框架,核心在于关键字的应用 目录 1.如何创建用户关键字 2.调用用户关键字 3.用户关键字的使用场景 1.如何创建关键字 第一种:直接在项目上右键,添加用 ...

  2. Oracle 无备份情况下的恢复--控制文件/数据文件

    13.3无备份恢复控制文件 没有备份恢复控制文件其实就是在nomount状态,create control创建一个新的控制文件. dba必须知道4个信息才能正确的创建:数据库名.在线日志路径及其大小. ...

  3. wcf restful 访问报错 *.svc HTTP error 404.17 - Not Found

    安装完成 iisreset,即使不重启也已经可以使用了

  4. 【ABAP系列】SAP ABAP 控制ALV单元格编辑后获取新的数值

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[ABAP系列]SAP ABAP 控制ALV单元 ...

  5. 应用安全 - 工具 | 平台 - Weblogic - 漏洞 - 汇总

    控制台路径 | 弱口令  前置条件 /console CVE-2016-0638  Date 类型远程代码执行 影响范围10.3.6, 12.1.2, 12.1.3, 12.2.1  CVE-2016 ...

  6. html5绘图笔记纪要

    在html5之前,前端是无法再html页面上动态绘制图片 html5新增了一个canvas元素,相当于一个画布,可以获取一个CanvasRenderingContext2D对象 CanvasRende ...

  7. 实验3&总结5

    老师:lijin2019,助教:晨晨果 提交作业 实验三 String类的应用 实验目的 掌握类String类的使用: 学会使用JDK帮助文档: 实验内容 1.已知字符串:"this is ...

  8. 路由器桥接时,为什么要关闭 DHCP 服务器?

    问:看网上的一些教程,路由器设置无线桥接的时候,副路由器中的 DHCP 服务器需要关闭,请问这是为什么? 答:两个路由器无线桥接时,之所以要关闭副路由器的 DHCP 服务器,是为了避免 IP 地址错误 ...

  9. [多校联考2019(Round 4 T2)][51nod 1288]汽油补给(ST表+单调栈)

    [51nod 1288]汽油补给(ST表+单调栈) 题面 有(N+1)个城市,0是起点N是终点,开车从0 -> 1 - > 2...... -> N,车每走1个单位距离消耗1个单位的 ...

  10. 【Python】循环结构中的else

    else在循环结构中,只有循环正常结束后才执行else,如果使用break跳出了循环,不会执行else for i in range(0,10): print(i)else: print(" ...