bzoj 1264 [AHOI2006]基因匹配Match dp + 树状数组
思路:好难想啊, 考虑到应该从每个数字只有5个数字下手, 但是不知道到底该怎么写。。
首先我们将第一个串按数字的种类分类, 每一类里面有5个, 然后将第二个串里面的数字一个一个加,如果一个加入的第 i 个数为5,
那么也只会对第一个串中的 5 产生影响, 如果第一个串中5的位置为pos, 那么显然dp[ i ][ pos ] = max(dp[ i ][ j ] , 0 < j < pos) + 1, 这个
过程我们用树状数组维护前缀最大和实现。
1 #include<bits/stdc++.h> 2 #define LL long long 3 #define fi first 4 #define se second 5 #define mk make_pair 6 #define pii pair<int,int> 7 #define piii pair<int, pair<int,int> > 8 9 using namespace std; 10 11 const int N = 1e5 + 10; 12 const int M = 10000 + 7; 13 const int inf = 0x3f3f3f3f; 14 const LL INF = 0x3f3f3f3f3f3f3f3f; 15 const int mod = 1e9 + 7; 16 const double eps = 1e-6; 17 18 int n, a[N], b[N]; 19 20 struct Bit { 21 int a[N]; 22 void modify(int pos, int v) { 23 for(int i = pos; i <= n; i += i & -i) { 24 a[i] = max(a[i], v); 25 } 26 } 27 28 int query(int pos) { 29 int ans = 0; 30 for(int i = pos; i; i -= i & -i) { 31 ans = max(ans, a[i]); 32 } 33 return ans; 34 } 35 }bit; 36 37 vector<int> v[N]; 38 39 int main() { 40 scanf("%d", &n); 41 n *= 5; 42 43 for(int i = 1; i <= n; i++) { 44 scanf("%d", &a[i]); 45 v[a[i]].push_back(i); 46 } 47 48 for(int i = 1; i <= n; i++) 49 reverse(v[i].begin(), v[i].end()); 50 51 int ans = 0; 52 for(int i = 1; i <= n; i++) { 53 int x; scanf("%d", &x); 54 for(int j = 0; j < v[x].size(); j++) { 55 int pos = v[x][j]; 56 int mx = bit.query(pos - 1); 57 ans = max(ans, mx + 1); 58 bit.modify(pos, mx + 1); 59 } 60 } 61 62 printf("%d\n", ans); 63 return 0; 64 } 65 66 /* 67 */