zoukankan      html  css  js  c++  java
  • 2019.01.26-bzoj2090: [Poi2010]Monotonicity 2

    题目描述:

    给出N个正整数a[1..N],再给出K个关系符号(>、<或=)s[1..k]。
    选出一个长度为L的子序列(不要求连续),要求这个子序列的第i项和第i+1项的的大小关系为s[(i-1)mod K+1]。
    求出L的最大值。

    算法标签:dp,树状数组

    思路:

    令f[i]为第i位能最多匹配到的选出的子序列的第几位。然后可以由前向后转移,用树状数组维护,小于和大于的情况,等于的用一个数组维护即可。

    讲的不清楚,其实看看代码也能很快理解。

    以下代码:

    #include<bits/stdc++.h>
    #define il inline
    #define _(d) while(d(isdigit(ch=getchar())))
    using namespace std;
    const int N=1e6+5;
    char s[5];
    int n,k,a[N],b[N],mx,t[2][N],p[N];
    il int read(){
        int x,f=1;char ch;
        _(!)ch=='-'?f=-1:f;x=ch^48;
        _()x=(x<<1)+(x<<3)+(ch^48);
        return f*x;
    }
    il void ins(int op,int x,int v){
        for(;x<=mx;x+=x&-x)t[op][x]=max(v,t[op][x]);
    }
    il int query(int op,int x){
        int res=0;
        for(;x;x-=x&-x)res=max(res,t[op][x]);
        return res;
    }
    int main()
    {
        n=read();k=read();
        for(int i=1;i<=n;i++)a[i]=read(),mx=max(a[i],mx);
        for(int i=1;i<=k;i++){
            scanf(" %s",s+1);
            if(s[1]=='<')b[i]=1;
            else if(s[1]=='=')b[i]=2;
            else b[i]=3;
        }
        int ans=0;
        for(int i=1;i<=n;i++){
            int x=max(p[a[i]],max(query(0,a[i]-1),query(1,mx-a[i])));
            int y=x%k+1;ans=max(ans,x+1);
            if(b[y]==1)ins(0,a[i],x+1);
            else if(b[y]==2)p[a[i]]=max(p[a[i]],x+1);
            else ins(1,mx-a[i]+1,x+1);
        }
        printf("%d
    ",ans);
        return 0;
    }
    View Code
  • 相关阅读:
    3.live555源码分析----延时队列
    RTP包的结构
    2.live555源码分析----服务端doEventLoop()函数分析
    1.live555源码分析----RSTPServer创建过程分析
    RTSP协议介绍 (转)
    搭建最简单的流媒体系统(服务器和客户端)
    谈一谈 MPU6050 姿态融合(转)
    Nginx的优化
    LAMP与LNMP加速与缓存优化
    Nginx在LNMP架构中的作用与虚拟主机配置
  • 原文地址:https://www.cnblogs.com/Jessie-/p/10325585.html
Copyright © 2011-2022 走看看