zoukankan      html  css  js  c++  java
  • 1264: [AHOI2006]基因匹配Match

    1264: [AHOI2006]基因匹配Match

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 982  Solved: 635
    [Submit][Status][Discuss]

    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

    Source

    TLE

    #include<cstdio>
    #include<iostream>
    using namespace std;
    int read(){
        register int x=0;bool f=1;
        register char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=0;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return f?x:-x;
    }
    const int N=1e5+10;
    int n,a[N],b[N],f[2][N];
    int main(){
        n=read();n*=5;
        for(int i=1;i<=n;i++) a[i]=read();
        for(int i=1;i<=n;i++) b[i]=read();
        int now=0;
        for(int i=1;i<=n;i++){
            now^=1;
            for(int j=1;j<=n;j++){
                if(a[i]==b[j]){
                    f[now][j]=f[now^1][j-1]+1;
                }
                else{
                    f[now][j]=max(f[now^1][j],f[now][j-1]);
                }
            }
        }
        printf("%d",f[now][n]);
        return 0;
    }

    AC

     

    //f[k]表示s2匹配到s1的k位置,最大公共子串的长度 
    #include<cstdio>
    #include<iostream>
    using namespace std;
    int read(){
        register int x=0;bool f=1;
        register char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=0;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return f?x:-x;
    }
    const int N=1e5+10;
    int n,ans,pos[N][6],f[N];
    int lowbit(int x){
        return x&-x;
    }
    void updata(int x,int val){
        for(int i=x;i<=n;i+=lowbit(i)) f[i]=max(f[i],val);
    }
    int query(int x){
        int res=0;
        for(int i=x;i;i-=lowbit(i)) res=max(res,f[i]);
        return res;
    }
    int main(){
        n=read();n*=5;
        for(int i=1,x;i<=n;i++) x=read(),pos[x][++pos[x][0]]=i;
        //加树状数组维护降至O(nlogn) 
        for(int i=1,x;i<=n;i++){
            x=read();
            for(int j=5;j;j--){
                int k=pos[x][j];//s1[j]=s2[1] 
                f[k]=max(f[k],query(k-1)+1);
                updata(k,f[k]);
                ans=max(ans,f[k]);
            }
        }
        printf("%d",ans);
        return 0;
    }
  • 相关阅读:
    有点忙啊
    什么是协程
    HDU 1110 Equipment Box (判断一个大矩形里面能不能放小矩形)
    HDU 1155 Bungee Jumping(物理题,动能公式,弹性势能公式,重力势能公式)
    HDU 1210 Eddy's 洗牌问题(找规律,数学)
    HDU1214 圆桌会议(找规律,数学)
    HDU1215 七夕节(模拟 数学)
    HDU 1216 Assistance Required(暴力打表)
    HDU 1220 Cube(数学,找规律)
    HDU 1221 Rectangle and Circle(判断圆和矩形是不是相交)
  • 原文地址:https://www.cnblogs.com/shenben/p/6255000.html
Copyright © 2011-2022 走看看