在这里,我们不二分,也不哈希,纯dp。但是复杂度真不行
可以知道,什么时候一个连续区间可以作为答案呢?前N个串称之为A集合,后N 个串称集合B。
假设这个连续区间是[L,R],长度是len,只有对于任意一个A中的串,在L位置与B中所有的串一一去比对,最长的相同的部分的的长度最多只能达到len - 1.
上面一段话是最重要也是我们dp的基础,为什么最长只能达到len - 1,如果最长相等部分达到len也就是[L,R]整个都一样,那么根据题意来说这是一个非法的连续区间,不能够作为答案。
设f[i][j][z] 代表A集合里面的i串与B集合里面的j串,在从z位置开始匹配,最长相同部分的串的长度。
显然
第z位的字符相同 则f[i][j][z] = f[i][j][z + 1] + 1,
第z位的字符不相同 则f[i][j][z] = 0.
然后对于每一个z,求出每一个i的f[i][j][z]的最大值为maxlen,然后关于z向前的区间的答案长度就是maxlen + 1,注意判断前面所说的非法情况。
在配合上滚动数组减少空间,
这样我们就可以在O(N^2*M)下完成这题。不开O2最大的点是540ms,开了O2最大的点是100ms,
int N, M,f[max_][max_];
char node[max_ << 1][max_];
il void ini() {
N = read(); M = read();
re int len,i, j,z,maxlen,ans = inf,Tm;
for (i = 1; i <= (N << 1); i++) {
scanf("%s", node[i] + 1);
// cin >> node[i] + 1;
}
for (len = 1, i = M; i >= 1; i--, len++) {
Tm = 0;
for (j = 1; j <= N; j++) {
maxlen = 0;
for (z = 1; z <= N; z++) {
if (node[j][i] == node[N + z][i]) {
f[j][z]++;
}
else {
f[j][z] = 0;
}
maxlen = max(maxlen, f[j][z]);
}
Tm = max(Tm, maxlen);
}
if (Tm != len) {
ans = min(ans, Tm + 1);
}
}
write(ans);
// cout << ans;
}
signed main() {
ini();
return 0;
}