【BZOJ1264】[AHOI2006]基因匹配Match【DP】【LCS】【树状数组】

【题目链接】

相对于一般的LCS来说,这个问题可以直接得到某个字符在字符串内的位置。

先把第一个串读入,处理出每个字符出现的位置。

然后枚举第二个串,对于当前的字符,直接枚举这个字符在第一个串里出现的位置,然后转移。

转移需要用到前缀最大值,用树状数组来维护。

orz神题。

/* Pigonometry */
#include <cstdio>
#include <algorithm>
#include <cstring>

using namespace std;

const int maxn = 20005, maxm = (maxn << 2) + maxn;

int n, m, cnt[maxn][7], dp[maxm], tr[maxm];

inline int iread() {
	int f = 1; int x = 0; char ch = getchar();
	for(; ch < '0' || ch > '9'; ch = getchar()) f = ch == '-' ? -1 : 1;
	for(; ch >= '0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - '0';
	return f * x;
}

inline void change(int x, int c) {
	for(; x <= m; x += x & -x) tr[x] = max(tr[x], c);
}

inline int query(int x) {
	int res = 0;
	for(; x; x -= x & -x) res = max(res, tr[x]);
	return res;
}

int main() {
	n = iread(); m = (n << 2) + n;
	for(int i = 1; i <= m; i++) {
		int x = iread();
		cnt[x][++cnt[x][0]] = i;
	}
	int ans = 0;
	for(int i = 1; i <= m; i++) {
		int x = iread();
		for(int j = 5; j >= 1; j--) {
			int pos = cnt[x][j], tmp = query(pos - 1) + 1;
			if(dp[pos] < tmp) dp[pos] = tmp, change(pos, tmp);
		}
	}
	for(int i = 1; i <= m; i++) ans = max(ans, dp[i]);
	printf("%d\n", ans);
	return 0;
}


你可能感兴趣的:(【BZOJ1264】[AHOI2006]基因匹配Match【DP】【LCS】【树状数组】)