Input file: master.in
Output file: master.out
Time limit: 1 seconds
Memory limit: 128 megabytes
所谓最长公共子串,比如串 A: “abcde”,串 B: “jcdkl”,则它们的最长公共子串为串 “cd”,即长度最长的字符串,且在两个串中都作为连续子串出现过。
给定两个长度都为 n 的字符串,对于字符串大师的你来说,求它们的最长公共子串再简单不过了。
所以现在你有 k 次修改机会,每次你可以选择其中某个串的某个位置,将其修改成任意字符。
你需要合理使用这 k 次修改机会,使得修改之后两个串的最长公共子串最长。相信对于字符串大师的你来说,这个问题也难不倒你。
Input
第一行包含两个整数 n; k,分别表示字符串的长度和修改次数。
第二行包含一个长度为 n 的仅由小写字符构成的字符串 S。
第三行包含一个长度为 n 的仅由小写字符构成的字符串 T。
Output
输出一行一个整数,即修改完毕之后两个串的最长公共子串的长度。
Examples
master.in | master.out |
5 0 abcde jcdkl |
2 |
5 2 aaaaa ababa |
5 |
Notes
对于 100% 的数据, 0 ≤ k ≤ n。
测试点编号 | n | k |
1 | = 5 | = 0 |
2 | = 10 | = 0 |
3 | = 10 | = 0 |
4 | = 10 | = 1 |
5 | = 10 | = 1 |
6 | = 100 | ≤ 100 |
7 | = 150 | ≤ 150 |
8 | = 200 | ≤ 200 |
9 | = 250 | ≤ 250 |
10 | = 300 | ≤ 300 |
分析
暴力和动规都可以写,时间复杂度都是O(n^3)。
代码
暴力枚举
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn=300+5; inline int read() { int x=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();} return x*f; } int n,k,ans; char a[maxn],b[maxn]; int main() { freopen("master.in","r",stdin); freopen("master.out","w",stdout); n=read();k=read(); scanf("%s%s",a+1,b+1); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) { int x=i,y=j,cnt=0; while(x<=n&&y<=n) { if(a[x]!=b[y]) cnt++; if(cnt>k) break; x++; y++; } ans=max(ans,x-i); } printf("%d ",ans); fclose(stdin); fclose(stdout); return 0; }