• [AHOI2006]基因匹配


    链接P4303 [AHOI2006]基因匹配

    • 求两个序列的最长公共子序列,满足每个数出现不超过(5)次,(nleq 10^5)
    • 一般的最长公共子序列是(O(n^2))的,考虑这个题的不一样性质在哪里。
    • 满足每个数出现不超过(5)次,意味合法的转移点不多。
    • 那么对于(a)序列中的每个数(a_i),他的合法转移点不会超过(5)个。
    • 所以把每个数的合法转移点扣出来,这样就得到了一个长度为(5*n)的序列。
    • 如果选择一个数,就相当于选择了一个转移点转移,因为要求是原串的子序列,所以转移点位置一定是单调上升的。
    • 所以对于每个数的合法转移点之间要倒序排列,这样才能满足一个数的转移点只会选择一个。
    • 现在问题转化成,给出一个长度为(5*n)的序列,求最长上升子序列。
    • 这个就烂大街了,树状数组或者二分栈随便维护一下即可,复杂度(O(5*nlogn))
    #include<bits/stdc++.h>
    #define R register int
    #define low(x) (x&(-x))
    using namespace std;
    const int N=20001;
    const int M=500001;
    int n,m,w[M],f[M],tot,ans,te[M];
    vector<int>G[N];
    void add(R x,R v){while(x<=m)te[x]=max(te[x],v),x+=low(x);}
    int query(R x){R v=0;while(x)v=max(te[x],v),x-=low(x);return v;}
    int gi(){
        R x=0,k=1;char c=getchar();
        while(c!='-'&&(c<'0'||c>'9'))c=getchar();
        if(c=='-')k=-1,c=getchar();
        while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+c-'0',c=getchar();
        return x*k;
    }
    int main(){
    	n=gi(),m=n*5;
    	for(R i=1,u;i<=m;++i)
    		u=gi(),G[u].push_back(i);
    	for(R i=1,u;i<=m;++i){
    		u=gi();
    		for(R j=4;j>=0;--j)w[++tot]=G[u][j];
    	}
    	for(R i=1;i<=tot;++i)
    		f[i]=query(w[i]-1)+1,add(w[i],f[i]),ans=max(ans,f[i]);
    	cout<<ans<<endl;
        return 0;
    }
    
    
    
  • 相关阅读:
    用R作Polar图等
    R语言绘制空间热力图
    Spark 基础及RDD基本操作
    Bars, rectangles with bases on x-axis
    spark dataframe操作集锦(提取前几行,合并,入库等)
    【R】用 ggplot2 绘制漂亮的分级统计地图
    Rattle:数据挖掘的界面化操作
    R语言进阶之4:数据整形(reshape)
    ggplot2——简介
    python复习冒泡排序
  • 原文地址:https://www.cnblogs.com/Tyher/p/9898976.html
Copyright © 2020-2023  润新知