zoukankan      html  css  js  c++  java
  • BZOJ_1264_[AHOI2006]基因匹配Match_树状数组

    BZOJ_1264_[AHOI2006]基因匹配Match_树状数组

    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

    2
    1 1 2 2 1 1 2 1 2 2
    1 2 2 2 1 1 2 2 1 1

    Sample Output

    7

    HINT

    [数据约束和评分方法]
    60%的测试数据中:1<=N <= 1 000
    100%的测试数据中:1<=N <= 20 000


    设F[i]表示第二个串以b[i]为结尾的最长公共序列。

    然后枚举每个i,找到a[i]对应的5个位置j。

    然后对每个位置求一遍前缀最大值来更新F[j]。

    这样做为什么是对的呢?

    首先在i后面那些位置肯定不会更新到F[j]。

    并且能够转移到F[j]的那些位置都已经被更新为最大值了。

    代码:

    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    using namespace std;
    #define N 100050
    int c[N],n,a[N],b[N],p[N][5],f[N],num[N];
    int inq(int x) {
        int re=0;
        x--;
        for(;x;x-=x&-x)re=max(re,c[x]);
        return re;
    }
    void fix(int x,int v) {
        for(;x<=n;x+=x&-x) c[x]=max(c[x],v);	
    }
    int main() {
        scanf("%d",&n);
        n*=5;	
        int i,j,ans=0;
        for(i=1;i<=n;i++) scanf("%d",&a[i]);
        for(i=1;i<=n;i++) scanf("%d",&b[i]),p[b[i]][num[b[i]]++]=i;
        for(i=1;i<=n;i++) {
            for(j=4;j>=0;j--) {
                int x=inq(p[a[i]][j]);
                f[p[a[i]][j]]=max(f[p[a[i]][j]],x+1);
                fix(p[a[i]][j],f[p[a[i]][j]]);
                ans=max(ans,f[p[a[i]][j]]);
            }
        }
        printf("%d
    ",ans);
    }
    
  • 相关阅读:
    Junit单元测试
    win7的6个网络命令
    WOJ1024 (POJ1985+POJ2631) Exploration 树/BFS
    WOJ1022 Competition of Programming 贪心 WOJ1023 Division dp
    woj1019 Curriculum Schedule 输入输出 woj1020 Adjacent Difference 排序
    woj1018(HDU4384)KING KONG 循环群
    woj1016 cherry blossom woj1017 Billiard ball 几何
    woj1013 Barcelet 字符串 woj1014 Doraemon's Flashlight 几何
    woj1012 Thingk and Count DP好题
    woj1010 alternate sum 数学 woj1011 Finding Teamates 数学
  • 原文地址:https://www.cnblogs.com/suika/p/9203612.html
Copyright © 2011-2022 走看看