UVA-1471(set+结构体+二分)

https://vjudge.net/problem/UVA-1471

#include<bits/stdc++.h>
using namespace std;
const int maxn = 200000 + 5;
int a[maxn], f[maxn], g[maxn];


struct Candidate{
    int a,g;
    Candidate(int a,int g):a(a),g(g){}
    bool operator<(const Candidate & rhs) const{
        return a<rhs.a;
    }
};

set<Candidate> s;

//只枚举以i开头的最长递增子序列,并通过二分思想或其它求出小于A[i]的且以j结尾的最长的递增子序列
int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        int n;
        scanf("%d",&n);
        for(int i=0;i<n;i++)
            scanf("%d",&a[i]);
        g[0]=1;
        for(int i=1;i<n;i++)
        if(a[i]>a[i-1])
            g[i]=g[i-1]+1;
        else    g[i]=1;

        f[n-1]=1;
        for(int i=n-2;i>=0;i--)
            if(a[i]<a[i+1])
            f[i]=f[i+1]+1;
            else f[i]=1;
        int ans=1;
        s.clear();
        for(int i=0;i<n;i++){
            Candidate c(a[i],g[i]);
            set<Candidate>::iterator it=s.lower_bound(c);
            // cout<<"it.a:"<<(*it).a<<endl;0
            // cout<<(it==s.begin())<<endl;true
            //当为空时,少返回为0,即加1
            bool keep=true;
            if(it!=s.begin()){
                Candidate last =*(--it) ;
                int len=f[i]+last.g;
                ans=max(ans,len);
                if(c.g<=last.g) keep=false;          }
            if(keep){
                s.erase(c);
                s.insert(c);
                it=s.find(c);
                it++;
                while(it!=s.end()&& it->g<=c.g) s.erase(it++);
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}
发布了239 篇原创文章 · 获赞 16 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_38662930/article/details/104317062