[AHOI2006] 基因匹配 Match
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1264
分析:
这个题拿到手时完全蒙蔽,写了个朴素的LCS果断TLE,后来看了某犇的博客,才知道有利用题目性质用树状数组做的方法。
这两天看了LCS问题转化为LIS问题的模型,想了一发:
对于每个在A串中的基因,在B中必然只有5个匹配点,所以如果转化成LIS,N只会变为原来5倍,即5*10^5,用O(nlogn)的LIS完全能跑过!
代码:
/**************************************************************
Problem: 1264
User: Krew
Language: C++
Result: Accepted
Time:472 ms
Memory:10588 kb
****************************************************************/
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <vector>
#define rep(i,x,y) for (int i=x;i<=y;i++)
#define dep(i,y,x) for (int i=y;i>=x;i--)
#define read(x) scanf("%d",&x)
using namespace std;
const int maxn=100000+23,INF=(1<<30);
int ans,N,n,rear,k,a[maxn*5],p[maxn*5],g[maxn*5],d[maxn*5];
vector<int> s[maxn];
int main()
{
read(N);
n=5*N;
rep(i,1,n)
read(a[i]);
rep(i,1,n)
{
read(k);
s[k].push_back(i);
}
rep(i,1,N)
sort(s[k].begin(),s[k].end());
rear=0;
rep(i,1,n)
dep(j,4,0) //只有5个匹配
p[++rear]=s[a[i]][j];
ans=0;
rep(i,0,rear) g[i]=INF;
rep(i,1,rear) //LIS
{
int l=lower_bound(g+1,g+rear+1,p[i])-g;
d[i]=l;
g[l]=p[i];
ans=max(ans,d[i]);
}
printf("%d\n",ans);
return 0;
}
好像不是很快……但是也比较好写吧……