欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

UVa1471 防线(DP,LIS优化)

程序员文章站 2022-03-12 17:59:56
...

本题要求在一个长度为n的序列中,删除一段连续子序列,使得剩下的序列有一个长度最大的连续递增子序列。
UVa1471 防线(DP,LIS优化)

#include<iostream>
#include<cstring>
#include<vector>
#include<algorithm>
#define maxn 300000
#define inf 1e9+100
using namespace std;
typedef long long ll;
ll T,n,A[maxn],tmp,f[maxn],g[maxn],d[maxn],ans;
int main(){
    cin>>T;
    while(T--){
        cin>>n;

        for(int i=1;i<=n;i++) cin>>A[i];
        //计算i结尾的最长长度 g[]
        for(int i=1;i<=n;i++){
            if(i==1) g[1]=1;
            else if(A[i]>A[i-1]) g[i]=g[i-1]+1;
            else g[i]=1;
        }
        //计算i开头的最长长度 f[]
        for(int i=n;i>=1;i--){
            if(i==n) f[i]=1;
            else if(A[i]<A[i+1]) f[i]=f[i+1]+1;
            else f[i]=1;
        } 
        for(int i=1;i<=n;i++) d[i]=inf;
        //solve,O(nlogn)
        d[1]=A[1];
        ans=1;
        for(int i=2;i<=n;i++){
            ll len=lower_bound(d+1,d+1+n,A[i])-d;
            ans=max(ans,len-1+f[i]);
            d[g[i]]=min(A[i],d[g[i]]);
        }
        cout<<ans<<endl;
    }
    return 0;
}