BZOJ 1264: [AHOI2006]基因匹配Match DP + 树状数组
由于有重复数字,我们以一个序列为基准,另一个序列以第一个序列每个数所在下标为这个序列每个数对应的值.
注意的是,拆值的时候按照在第一个序列中的位置从大到小排,强制只能选一个.
最后跑一边最长上升子序列即为答案
Code:
#include <bits/stdc++.h> #define setIO(s) freopen(s".in","r",stdin) #define maxn 2000000 using namespace std; int col[maxn][7],cnt[maxn], arr[maxn], w[maxn], ans; struct BIT { int C[maxn]; int lowbit(int t) { return t & (-t); } void update(int x,int t) { while(x < maxn) C[x] = max(C[x], t), x += lowbit(x); } int query(int x) { int res = 0; while(x > 0) { res = max(res, C[x]); x -= lowbit(x); } return res; } }tree; int main() { // setIO("input"); int m,n; scanf("%d",&m), n = m * 5; for(int i = 1,k;i <= n; ++i) { scanf("%d",&k); col[k][++cnt[k]] = i; } memset(cnt,0,sizeof(cnt)); int tot = 0; for(int i = 1,k;i <= n; ++i) { scanf("%d",&k); for(int j = 5;j >= 1; --j) arr[++tot] = col[k][j]; } for(int i = 1;i <= tot; ++i) { int k = tree.query(arr[i]) + 1; ans = max(ans,k); tree.update(arr[i] + 1, k); } printf("%d",ans); return 0; }