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 000php

Source

TLEios

#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;
}
相關文章
相關標籤/搜索