GDOI 2016 Day1 T2 最长公共子串
来源:互联网 发布:身份证复印件软件下载 编辑:程序博客网 时间:2024/05/22 00:28
Description
给出两个字符串A和B,求最长公共子串。
其中B串中有k个区间的字符可以任意调换。
|A|,|B|<=2000,k<=100000
Solution
首先,一个很明显的性质,两个区间如果有交集,那么这两个区间可以合并成一个。
然后,k就可以降到2000级别了。
开始乱搞。
你可以选择双指针往后推,也可以使用DP。
这里介绍后者。
设f[i,j]表示以A串的第i位和B串的第j位结尾的最长公共子串。
则有两种情况。
一是这个区间中的东西够用。
处理出A串的前缀和和B串每个区间的字符个数即可。
二是这个区间有东西,但不够。
那么我们可以减少一个这个位子的字符的使用。
处理出A串每个位置往后第一个字符的位置即可。
Code
#include<cstdio>#include<cstring>#include<algorithm>#define fo(i,a,b) for(int i=a;i<=b;i++)#define fd(i,a,b) for(int i=a;i>=b;i--)#define N 2005using namespace std;struct note{int l,r;}ask[102005];bool cmp(note x,note y) {return x.l<y.l;}char s[N],st[N];int n,m,l,r,k,ans,a[N],b[N],sum[N][26],c[N][26];int f[N][N],left[N],next[N][26],cnt[26];int main() { freopen("lcs.in","r",stdin); freopen("lcs.out","w",stdout); scanf("%s",s+1);n=strlen(s+1);fo(i,1,n) a[i]=s[i]-'a'; scanf("%s",st+1);m=strlen(st+1);fo(i,1,m) b[i]=st[i]-'a'; scanf("%d",&k); fo(i,1,k) scanf("%d%d",&ask[i].l,&ask[i].r),ask[i].l++,ask[i].r++; fo(i,k+1,k+m) ask[i].l=ask[i].r=i-k;k+=m; sort(ask+1,ask+k+1,cmp);l=ask[1].l;r=ask[1].r; fo(i,2,k) if (ask[i].l>r) { fo(j,0,25) cnt[j]=0; fo(j,l,r) left[j]=l,cnt[b[j]]++; fo(j,l,r) fo(t,0,25) c[j][t]=cnt[t]; l=ask[i].l;r=ask[i].r; } else r=max(r,ask[i].r); fo(j,0,25) cnt[j]=0; fo(j,l,r) left[j]=l,cnt[b[j]]++; fo(j,l,r) fo(t,0,25) c[j][t]=cnt[t]; fo(i,1,n) { fo(j,0,25) sum[i][j]=sum[i-1][j]; sum[i][a[i]]++; } fd(i,n,1) { fo(j,0,25) next[i][j]=next[i+1][j]; next[i][a[i]]=i; } fo(i,1,n) fo(j,1,m) { int x=a[i]; k=max(i-f[i-1][j-1],i-j+left[j]); if (sum[i-1][x]-sum[k-1][x]<c[j][x]) f[i][j]=f[i-1][j-1]+1; else if (next[k][x]&&next[k][x]<i&&c[j][x]) f[i][j]=i-next[k][x]; ans=max(ans,f[i][j]); } printf("%d",ans);}
0 0
- GDOI 2016 Day1 T2 最长公共子串
- 【GDOI 2016 Day1】第二题 最长公共子串
- 【GDOI 2016 Day1】第二题 最长公共子串
- 【GDOI 2016 Day1】第二题 最长公共子串 题解+代码
- JZOJ.4486 【GDOI 2016 Day1】第二题 最长公共子串
- 【JZOJ 4486】【GDOI 2016 Day1】第二题 最长公共子串
- 【GDOI 2016 】最长公共子串
- Noip2015 Day1 T2 子串(Dp)
- 最长公共子串
- 最长公共子串
- 最长公共子串
- 最长公共子串
- 最长公共子串
- 最长公共子串
- 最长公共子串
- 最长公共子串
- 最长公共子串
- 最长公共子串
- 网络请求——XML解析
- activiti 自定义用户、组
- thinkphp3.2,URL重写
- 栈
- 圆柱
- GDOI 2016 Day1 T2 最长公共子串
- excel 2003代码
- 磁盘排序算法(多路归并、位图)
- android异步任务及接口回调传输数据
- github代码上传(初学)
- Property Animation(属性动画)
- Css技术入门笔记01
- Amazon : 找出所给数字的下一个回文数
- Android系统中Parcelable和Serializable的区别