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 */

 

posted @ 2018-05-31 21:26  NotNight  阅读(112)  评论(0编辑  收藏  举报