• 【二分】Defense Lines


    [UVa1471] Defense Lines

    算法入门经典第8章8-8 (P242)

    题目大意:将一个序列删去一个连续子序列,问最长的严格上升子序列 (N<=200000)

    试题分析:算法1:直接暴力,对于一个删除序列,枚举头和尾,然后看最长上升子序列。时间复杂度:O(N^3)

         算法2:L[i]表示以i为结尾的最长严格上升子序列长度,R[i]表示以i为开头的最长严格上升子序列长度。 预处理:O(N)

              然后依旧是枚举头和尾,那么答案就是L[i]+R[j]了。时间复杂度:O(N^2)

         算法3:第一个与第二个时间复杂度对于题目来说都非常之高,所以O(NlogN)是我们需要的。

              预处理是必须要的,这样能除以O(N)。

              下面要改进的就是这个枚举i,j的循环了,能不能确定j(i),来唯一确定最优的i(j)呢?

              到这里,性质就比较显然了,我们需要用一个数据结构来维护它。

              那么具体用什么呢?这就是单调队列的典型问题了。

              可以发现,如果a[i']>=a[i] , 且L(i')>=L(i),那么要i是没有用的,因为i'更优或者余地更大了。

              然后维护这样一个数组,每次二分仅次于A[i]的值相加就好了。

              可能有些抽象,具体请看代码。

    代码:

    #include<iostream>
    #include<cstring>
    #include<vector>
    #include<queue>
    #include<algorithm>
    using namespace std;
    
    #define LL long long
    
    inline int read(){
    	int x=0,f=1;char c=getchar();
    	for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
    	for(;isdigit(c);c=getchar()) x=x*10+c-'0';
    	return x*f;
    }
    const int INF=2147483640;//注意a[i]<=1e9,要开大一点
    const int MAXN=2000001;
    int L[MAXN+1],R[MAXN+1];
    int N; int T;
    int a[MAXN+1]; int Que[MAXN+1];
    int FLen; int ans;
    
    int main(){
    	T=read();
    	while(T--){
    		N=read();
    		for(int i=1;i<=N;i++) a[i]=read();
    		L[1]=1,R[N]=1;//预处理
    		for(int i=2;i<=N;i++){
    			L[i]=1;
    			if(a[i]>a[i-1]) L[i]+=L[i-1];
    		}
    		for(int i=N-1;i>=1;i--){
    			R[i]=1;
    			if(a[i]<a[i+1]) R[i]+=R[i+1];
    		}
    		ans=0;
    		for(int i=1;i<=N;i++) Que[i]=INF;
    		for(int i=1;i<=N;i++){
    			FLen=lower_bound(Que+1,Que+1+N,a[i])-Que;//二分第一个大于等于于a[i]的值
    			ans=max(ans,FLen+R[i]-1);//计算长度,由于lower_bound是大于等于,所以要-1,让其变成第一个<a[i]
    			Que[L[i]]=min(Que[L[i]],a[i]);//相同的最后如果越小,后面的潜力越大
    		}
    		printf("%d
    ",ans);
    	}
    	return 0;
    }
            
    

     

      

     

  • 相关阅读:
    Linux tcpdump 命令详解与示例
    Linux 查看磁盘IO并找出占用IO读写很高的进程
    Rsync 服务部署与参数详解
    Linux curl 表单登录或提交与cookie使用
    Linux curl 常用示例
    Linux curl 命令详解
    Linux下使用 github+hexo 搭建个人博客07-next主题接入搜索和站点管理
    Linux下使用 github+hexo 搭建个人博客06-next主题接入数据统计
    Linux下使用 github+hexo 搭建个人博客05-next主题接入评论系统
    Linux下使用 github+hexo 搭建个人博客04-next主题优化
  • 原文地址:https://www.cnblogs.com/wxjor/p/7501850.html
Copyright © 2020-2023  润新知