【题目链接】
相对于一般的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; }