洛谷P3667 [USACO17OPEN]Bovine Genomics G 动态规划

这篇博客探讨了一种使用动态规划解决字符串匹配问题的方法。在不使用二分查找或哈希函数的情况下,通过构建连续区间的条件,找到最长不完全相同的子串。博主通过状态转移方程描述了动态规划的状态,并利用滚动数组优化了空间复杂度,最终实现了O(N^2*M)的时间复杂度解题方案。
摘要由CSDN通过智能技术生成

在这里,我们不二分,也不哈希,纯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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值