BZOJ1264——[AHOI2006]基因匹配Match

1、题意,求最长公共子序列,每个数字在序列中都出现5次

2、分析:最长公共子序列的标准解法是dp,$O(n^2)$过不了的,然后我们发现判断哪两个位置优化的地方用$5n$就可以搞定了,那么我们用BIT优化一波,就AC了

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;
#define M 100010
 
inline int read(){
    char ch = getchar(); int x = 0, f = 1;
    while(ch < '0' || ch > '9'){
        if(ch == '-') f = -1;
        ch = getchar();
    }
    while('0' <= ch && ch <= '9'){
        x = x * 10 + ch - '0';
        ch = getchar();
    }
    return x * f;
}
 
int pos[M][6], cnt[M];
int c[M];
int n, f[M];
 
inline void change(int x, int k){
    for(; x <= n; x += (x & -x)) c[x] = max(c[x], k);
}
 
inline int get_ans(int x){
    int ret = 0;
    for(; x > 0; x -= (x & -x)) ret = max(ret, c[x]);
    return ret;
}
 
int main(){
    n = read() * 5;
    for(int i = 1; i <= n; i ++){
        int x = read();
        pos[x][++ cnt[x]] = i;
    }
    int ans = 0;
    for(int i = 1; i <= n; i ++){
        int x = read();
        for(int j = 5; j >= 1; j --){
            int k = pos[x][j];
            f[k] = max(f[k], get_ans(k - 1) + 1);
            change(k, f[k]);
            ans = max(ans, f[k]);
        }
    }
    printf("%d\n", ans);
    return 0;
}


你可能感兴趣的:(dp,bzoj,1264,基因匹配Match,AHOI2006)