BZOJ1264: [AHOI2006]基因匹配Match
2014-10-11 13:08
253 查看
1264: [AHOI2006]基因匹配Match
Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 541 Solved: 347
[Submit][Status]
Description
基因匹配(match)
卡卡昨天晚上做梦梦见他和可可来到了另外一个星球,这个星球上生物的DNA序列由无数种碱基排列而成(地球上只有4种),而更奇怪的是,组成DNA序列的
每一种碱基在该序列中正好出现5次!这样如果一个DNA序列有N种不同的碱基构成,那么它的长度一定是5N。
卡卡醒来后向可可叙述了这个奇怪的梦,而可可这些日子正在研究生物信息学中的基因匹配问题,于是他决定为这个奇怪星球上的生物写一个简单的DNA匹配程
序。
为了描述基因匹配的原理,我们需要先定义子序列的概念:若从一个DNA序列(字符串)s中任意抽取一些碱基(字符),将它们仍按在s中的顺序排列成一个新
串u,则称u是s的一个子序列。对于两个DNA序列s1和s2,如果存在一个序列u同时成为s1和s2的子序列,则称u是s1和s2的公共子序列。
卡卡已知两个DNA序列s1和s2,求s1和s2的最大匹配就是指s1和s2最长公共子序列的长度。
[任务]
编写一个程序:
从输入文件中读入两个等长的DNA序列;
计算它们的最大匹配;
向输出文件打印你得到的结果。
Input
输入文件中第一行有一个整数N,表示这个星球上某种生物使用了N种不同的碱基,以后将它们编号为1…N的整数。以下还有两行,每行描述一个DNA序列:包含5N个1…N的整数,且每一个整数在对应的序列中正好出现5次。
Output
输出文件中只有一个整数,即两个DNA序列的最大匹配数目。Sample Input
21 1 2 2 1 1 2 1 2 2
1 2 2 2 1 1 2 2 1 1
Sample Output
7HINT
[数据约束和评分方法]60%的测试数据中:1<=N <= 1 000
100%的测试数据中:1<=N <= 20 000
Source
题解:这真是一道好题!
因为最传统的LCS的做法中,最大值更新的条件是 s[1][i]==s[2][j],
而现在对于每一个 s[1][i],我们已经知道s[2]中哪些元素与它相同,显然可以用这些元素的前缀最大值+1来更新这个点的最优值。
因为前面已经匹配过的一定是合法的,所以我们将i与该元素匹配得到一个更大的答案。
树状数组再次发挥了前缀最大值的快速查询的作用。
真是一道巧妙的题!
代码:
#include<cstdio> #include<cstdlib> #include<cmath> #include<cstring> #include<algorithm> #include<iostream> #include<vector> #include<map> #include<set> #include<queue> #include<string> #define inf 1000000000 #define maxn 20000+100 #define maxm 500+100 #define eps 1e-10 #define ll long long #define pa pair<int,int> #define for0(i,n) for(int i=0;i<=(n);i++) #define for1(i,n) for(int i=1;i<=(n);i++) #define for2(i,x,y) for(int i=(x);i<=(y);i++) #define for3(i,x,y) for(int i=(x);i>=(y);i--) #define mod 1000000007 using namespace std; inline int read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();} return x*f; } int n,ans,p[maxn][6],s[5*maxn],f[5*maxn]; void change(int x,int y) { for(;x<=5*n;x+=x&(-x))s[x]=max(s[x],y); } int ask(int x) { int t=0; for(;x;x-=x&(-x))t=max(t,s[x]); return t; } int main() { freopen("input.txt","r",stdin); freopen("output.txt","w",stdout); n=read(); for1(i,5*n){int x=read();p[x][++p[x][0]]=i;} for1(i,5*n) { int x=read(); for3(j,5,1) { int y=p[x][j],t=ask(y-1)+1; if(t>f[y])f[y]=t,change(y,t); } } for1(i,5*n)ans=max(ans,f[i]); printf("%d\n",ans); return 0; }
View Code
相关文章推荐
- BZOJ1264 [AHOI2006]基因匹配Match 【LCS转LIS】
- BZOJ_1264_[AHOI2006]基因匹配Match_树状数组
- bzoj 1264: [AHOI2006]基因匹配Match 树状数组
- bzoj 1264 [AHOI2006]基因匹配Match(DP+树状数组)
- [BZOJ1264][AHOI2006]基因匹配Match(DP + 树状数组)
- bzoj1264 [AHOI2006]基因匹配Match (树状数组优化DP)
- BZOJ 1264 AHOI2006 基因匹配Match 动态规划+树状数组
- BZOJ 1264: [AHOI2006]基因匹配Match 树状数组+DP
- bzoj 1264: [AHOI2006]基因匹配Match
- bzoj 1264: [AHOI2006]基因匹配Match
- BZOJ1264: [AHOI2006]基因匹配Match
- BZOJ 1264: [AHOI2006]基因匹配Match( LCS )
- bzoj 1264: [AHOI2006]基因匹配Match(树状数组)
- [bzoj1264][AHOI2006]基因匹配Match 树状数组优化dp
- BZOJ 1264 AHOI2006 基因匹配Match 动态规划+树状数组
- 【BZOJ1264】【AHOI2006】基因匹配Match (dp+树状数组)
- 【BZOJ1264】[AHOI2006]基因匹配Match【DP】【LCS】【树状数组】
- bzoj 1264: [AHOI2006]基因匹配Match
- bzoj 1264 [AHOI2006]基因匹配Match(DP+树状数组)
- BZOJ 1264: [AHOI2006]基因匹配Match|动态规划