zoukankan      html  css  js  c++  java
  • 【GMOJ4486】最长公共子串

    题目

    题目链接:https://gmoj.net/senior/#main/show/4486

    (n,mleq 2000,kleq 10^5)

    思路

    首先如果两个段有交,那么可以把这两个段合并起来。
    然后对于 (S) 串中任意一个字符 (c),如果它没有被任何区间覆盖,那么可以再加入一个长度为 (1) 的区间覆盖它。
    然后考虑 dp。设 (f[i][j]) 表示 (S) 串的第 (i) 个区间与 (T) 串的第 (j) 个字符开始,往后最多能匹配的位数。这个可以直接枚举求出,用桶来维护是否可行。
    再设 (g[i][j]) 表示 (S) 串第 (i) 个区间到最后一个区间,与 (T) 串位置 (j) 开始,且这 (f[i][j]) 个字符必须全部匹配时,往后能最大匹配的位数。只需要判断一下第 (i+1) 个区间是否全部匹配上 (T) 即可。
    然后枚举第 (i) 个区间匹配的长度求最大值即可。
    时间复杂度 (O(nm))

    代码

    #include <bits/stdc++.h>
    using namespace std;
    
    const int N=2010,M=110010,Inf=1e9;
    int n,m,k,ans,cnt,bel[N],c[N][27],d[27],f[N][N],g[N][N];
    char s[N],t[N];
    
    struct node
    {
    	int l,r;
    }a[M];
    
    bool cmp(node x,node y)
    {
    	return x.l<y.l;
    }
    
    int main()
    {
    	freopen("lcs.in","r",stdin);
    	freopen("lcs.out","w",stdout);
    	scanf("%s%s%d",t+1,s+1,&k);
    	n=strlen(s+1); m=strlen(t+1);
    	for (int i=1;i<=k;i++)
    	{
    		scanf("%d%d",&a[i].l,&a[i].r);
    		a[i].l++; a[i].r++;
    	}
    	for (int i=1;i<=n;i++)
    		a[++k]=(node){i,i};
    	sort(a+1,a+1+k,cmp);
    	for (int i=1;i<=k;i++)
    		if (a[i].l<=a[cnt].r) a[cnt].r=max(a[cnt].r,a[i].r);
    			else a[++cnt]=a[i];
    	k=cnt;
    	for (int i=1;i<=k;i++)
    		for (int j=a[i].l;j<=a[i].r;j++)
    			bel[j]=i,c[i][s[j]-'a']++;
    	for (int i=k;i>=1;i--)
    		for (int j=m;j>=1;j--)
    		{
    			int len=a[i].r-a[i].l,l=j;
    			for (;l<=min(j+len,m);l++)
    			{
    				if (c[i][t[l]-'a']==d[t[l]-'a']) break;
    				d[t[l]-'a']++;
    			}
    			f[i][j]=l-j;
    			if (f[i+1][l]==a[i+1].r-a[i+1].l+1)
    				g[i][j]=f[i][j]+g[i+1][l];
    			else
    				g[i][j]=f[i][j]+f[i+1][l];
    			for (int p=j;p<=l;p++)
    			{
    				if (p!=l) d[t[p]-'a']--;
    				if (f[i+1][p]==a[i+1].r-a[i+1].l+1)
    					ans=max(ans,p-j+g[i+1][p]);
    				ans=max(ans,p-j+f[i+1][p]);
    			}
    		}
    	cout<<ans;
    	return 0;
    }
    
  • 相关阅读:
    Redis配置文件详解
    linux系统配置Apache虚拟主机实例
    nginx File not found 错误分析与解决方法
    svn配置使用
    linux下svn命令使用大全
    Kendo UI For ASP.NET MVC项目资源
    ReSharper 配置及用法
    SQL判断某列中是否包含中文字符、英文字符、纯数字 (转)
    Visual Studio最好用的快捷键
    19个必须知道的Visual Studio快捷键
  • 原文地址:https://www.cnblogs.com/stoorz/p/15002491.html
Copyright © 2011-2022 走看看