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
  • 相关阅读:
    支付清结算之基本概念和入门
    支付清结算之账户和账务处理
    支付系统设计:支付系统的账户模型(一)
    Docker架构和原理
    Docker容器的原理、特征、基本架构、与应用场景
    Docker的用途与原理
    Random函数的安全性问题与SecureRandom
    nginx配置https
    CentOS Docker 安装
    Nginx能做什么
  • 原文地址:https://www.cnblogs.com/Jessie-/p/10325585.html
Copyright © 2011-2022 走看看