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

    bzoj1264[AHOI2006]基因匹配Match

    题意:

    某种序列由n种数组成,每种数在该序列中正好出现5次。对于两个这样的序列s1和s2,如果存在一个序列u同时成为s1和s2的子序列,则称u是s1和s2的公共子序列。子序列的概念:若从一个序列s中任意抽取一些数字,将它们仍按在s中的顺序排列成一个新串u,则称u是s的一个子序列。已知两个等长DNA序列s1和s2,求s1和s2最长公共子序列的长度。

    题解:

    dp+树状数组,题解太难写,摘抄一下

    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)

    代码:

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #include <queue>
     5 #define inc(i,j,k) for(int i=j;i<=k;i++)
     6 #define dec(i,j,k) for(int i=j;i>=k;i--)
     7 #define lb(x) x&-x
     8 using namespace std;
     9 
    10 int c[200000],n,a[40000][6],an[40000],f[200000],ans;
    11 inline int query(int x){int q=0; while(x)q=max(q,c[x]),x-=lb(x); return q;}
    12 inline void update(int x,int y){while(x<=n*5)c[x]=max(c[x],y),x+=lb(x);}
    13 int main(){
    14     scanf("%d",&n); memset(an,0,sizeof(an)); memset(c,0,sizeof(c));
    15     inc(i,1,n*5){int x; scanf("%d",&x); a[x][++an[x]]=i;} ans=0;
    16     memset(f,0,sizeof(f));
    17     inc(i,1,n*5){
    18         int x; scanf("%d",&x);
    19         dec(j,5,1){
    20             int y=a[x][j]; f[y]=max(f[y],query(y-1)+1);
    21             update(y,f[y]); ans=max(ans,f[y]);
    22         }
    23     }
    24     printf("%d",ans);
    25     return 0;
    26 }

    20160423

  • 相关阅读:
    http://www.codeplex.com/ 一个不错的开源网站
    阳光灿烂每一天z
    Mercurial使用简单介绍zz
    德国人的记事本 zz
    你一定要知道的71个做饭技巧
    推荐一个原型设计软件 Balsamiq Mockups
    不能一起吃的食物
    雷电预防
    马云 + 史玉柱的40条经典语录zz
    (转)扩展ArcGIS API for Silverlight/WPF 中的TextSymbol支持角度标注
  • 原文地址:https://www.cnblogs.com/YuanZiming/p/5703348.html
Copyright © 2011-2022 走看看