BZOJ 1264 基因匹配Match(LCS转化LIS)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1264

题意:给出两个数列,每个数列的长度为5n,其中1-n每个数字各出现5次。求两个数列的最长公共子列。

思 路:首先找出每个数字在第二个数列中出现的位置,对于第一个数列构造出一个新的数列,每个数用这个数在第二个数列中出现的5个位置代替。这样求最长上升子 列。注意的是,在求到每个数(这里指原第一个数列中的每个数)为止的LIS时,替换后的5个数字要先求大的。。不清楚的看代码。

 

int a[N*5],b[N*5],n;

vector<int> V[N];

int s[N*5];









void add(int x,int t)

{

    while(x<N*5)

    {

        if(s[x]<t) s[x]=t;

        x+=x&-x;

    }

}





int get(int x)

{

    int ans=0;

    while(x)

    {

        if(s[x]>ans) ans=s[x];

        x-=x&-x;

    }

    return ans;

}





int main()

{

    RD(n);

    int i,j;

    FOR1(i,n*5) RD(a[i]);

    FOR1(i,n*5) RD(b[i]),V[b[i]].pb(i);

    int ans=0,temp,x;

    for(i=1;i<=n*5;i++)

    {

        for(j=4;j>=0;j--)

        {

            x=V[a[i]][j];

            temp=get(x-1)+1;

            if(temp>ans) ans=temp;

            add(x,temp);

        }

    }

    PR(ans);

}

 

 

 

你可能感兴趣的:(match)