• [bzoj1264]基因匹配


    首先朴素dp的方程,即$f[i][j]=max(f[i][j-1],f[i-1][j],(a[i]==b[j])*(f[i-1][j-1]+1))$,这中间特殊的转移只在a[i]=b[j]时,而在这道题中与a[i]相等的b[j]只有5个,考虑利用这一性质
    先预处理每一种数的位置,在枚举i的同时,用线段树来维护f[i]这个数组,然后对于特殊的5个位置从上一轮转移,并对后面的区间max即可

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define N 100005
     4 #define L (k<<1)
     5 #define R (L+1)
     6 #define mid (l+r>>1)
     7 int n,x,a[N],b[N][11],f[N<<2];
     8 void down(int k){
     9     f[L]=max(f[L],f[k]);
    10     f[R]=max(f[R],f[k]);
    11     f[k]=0;
    12 }
    13 void update(int k,int l,int r,int x,int y,int z){
    14     if ((l>y)||(x>r))return;
    15     if ((x<=l)&&(r<=y)){
    16         f[k]=max(f[k],z);
    17         return;
    18     }
    19     down(k);
    20     update(L,l,mid,x,y,z);
    21     update(R,mid+1,r,x,y,z);
    22 }
    23 int query(int k,int l,int r,int x){
    24     if (!x)return 0;
    25     if (l==r)return f[k];
    26     down(k);
    27     if (x<=mid)return query(L,l,mid,x);
    28     return query(R,mid+1,r,x);
    29 }
    30 int main(){
    31     scanf("%d",&n);
    32     n*=5;
    33     for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    34     for(int i=1;i<=n;i++){
    35         scanf("%d",&x);
    36         b[x][++b[x][0]]=i;
    37     }
    38     for(int i=1;i<=n/5;i++)b[i][6]=n+1;
    39     for(int i=1;i<=n;i++)
    40         for(int j=5;j;j--)
    41             update(1,1,n,b[a[i]][j],b[a[i]][j+1]-1,query(1,1,n,b[a[i]][j]-1)+1);
    42     printf("%d",query(1,1,n,n));
    43 }
    View Code
  • 相关阅读:
    print格式化输出(format)
    Python list,tuple,dict,set高级变量常用方法
    K8s的kubectl常用命令
    C/C++中数组与指针的关系探究
    Java中的不可变类
    JAVA 类总结
    c++ string类find总结
    关于看板娘的事儿
    类型转换
    计算机2进制小数点表示法
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/12493076.html
Copyright © 2020-2023  润新知