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);
}

BZOJ 1264 基因匹配Match(LCS转化LIS),布布扣,bubuko.com

时间: 2024-08-05 06:39:42

BZOJ 1264 基因匹配Match(LCS转化LIS)的相关文章

BZOJ 1264: [AHOI2006]基因匹配Match( LCS )

序列最大长度2w * 5 = 10w, O(n²)的LCS会T.. LCS 只有当a[i] == b[j]时, 才能更新答案, 我们可以记录n个数在第一个序列中出现的5个位置, 然后从左往右扫第二个序列时将第一个序列对应位置的值更新, 用树状数组维护. 时间复杂度O(nlogn) ------------------------------------------------------------------------------------------------- #include<bi

bzoj1264 基因匹配Match (lcs转lis lcs(nlogn))

基因匹配Match 内存限制:256 MiB 时间限制:1000 ms 标准输入输出 题目描述 基因匹配(match) 卡卡昨天晚上做梦梦见他和可可来到了另外一个星球,这个星球上生物的DNA序列由无数种碱基排列而成(地球上只有4种),而更奇怪的是,组成 DNA序列的每一种碱基在该序列中正好出现5次!这样如果一个DNA序列有N种不同的碱基构成,那么它的长度一定是5N. 卡卡醒来后向可可叙述了这个奇怪的梦,而可 可这些日子正在研究生物信息学中的基因匹配问题,于是他决定为这个奇怪星球上的生物写一个简单

BZOJ-1264 :[AHOI2006]基因匹配Match(树状数组+DP)

1264: [AHOI2006]基因匹配Match Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 904  Solved: 578[Submit][Status][Discuss] Description 基因匹配(match) 卡卡昨天晚上做梦梦见他和可可来到了另外一个星球,这个星球上生物的DNA序列由无数种碱基排列而成(地球上只有4种),而更奇怪的是,组成DNA序列的每一种碱基在该序列中正好出现5次!这样如果一个DNA序列有N种不同的碱基构成

BZOJ 1264 [AHOI2006]基因匹配Match

有一定思维难度的题目..看了mps大爷的题解才会做(%%% mps) 考虑暴力O(n^2)dp的算法,只有当A[i] == B[j]时才会+1.我们可以利用这个性质,记录下每个数在A[i]中的5个位置.然后从前往后扫描B,顺便转移.转移时要维护前缀max,这个可以用树状数组随意维护一下.时间复杂度是O(nlogn)的 具体看代码 1 //F[i]表示B与A中前i个数的LCS长度 2 3 #include <cstdio> 4 #include <algorithm> 5 6 usi

bzoj 1264: [AHOI2006]基因匹配Match (树状数组优化dp)

链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1264 思路: n大小为20000*5,而一般的dp求最长公共子序列复杂度是 n*n的,所以我们必须优化. 题目说了一个数会出现5次,那么我们可以预处理得到 第一个序列a[]每个数字分别在哪些位置, 因为求LCS的状态转移方程中当 s1[i-1] == s2[j-1]时,dp[i][j] = dp[i-1][j-1] + 1;只有当两个点相同时 值才会+1,我们可以对第二个序列b[]遍历一遍

BZOJ 1264 AHOI2006 基因匹配Match 动态规划+树状数组

题目大意:给定n个数和两个长度为n*5的序列,每个数恰好出现5次,求两个序列的LCS n<=20000,序列长度就是10W,朴素的O(n^2)一定会超时 所以我们考虑LCS的一些性质 LCS的决策+1的条件是a[i]==b[j] 于是我们记录a序列中每个数的5个位置 扫一下b[i] 对于每个b[i]找到b[i]在a中的5个位置 这5个位置的每个f[pos]值都可以被b[i]更新 于是找到f[1]到f[pos-1]的最大值+1 更新f[pos]即可 这个用树状数组维护 时间复杂度O(nlogn)

BZOJ1264 [AHOI2006]基因匹配Match 动态规划 树状数组

欢迎访问~原文出处--博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1264 题意概括 给出两个长度为5*n的序列,每个序列中,有1~n各5个. 求其最长公共子序列长度. 题解 我们发现这题的序列特殊性是关键! 我们只需要知道每一种数字在某一个序列中的5个位置,然后对于普通的LCS问题,我们只有在a[i] = b[j]的时候才会+1. 那么我们可以维护一个树状数组,在a序列中,我们一个一个位置扫过去,每次通过树状数组维护的前缀最大值来更新,然后因为修改不多,所以维护

BZOJ1264: [AHOI2006]基因匹配Match

题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1264 因为每个字符至多出现5次,在A中记录下来.然后在B中扫一遍,因为a[i]=b[j]时f[i]++,所以维护一个树状数组记录最大值就可以了. 注意转移的顺序 #include<cstring> #include<iostream> #include<cstdio> #include<map> #include<cmath> #includ

[BZOJ1264][AHOI2006]基因匹配Match(DP + 树状数组)

传送门 有点类似LCS,可以把 a[i] 在 b 串中的位置用一个链式前向星串起来,由于链式前向星是从后往前遍历,所以可以直接搞. 状态转移方程 f[i] = max(f[j]) + 1 ( 1 <= j  < i && a[i] == b[j] ) ——代码 1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 5 using namespace std; 6 7