LST最长上升子序列 和非升序序列

4 篇文章 0 订阅
//ss同学的最长上升子序列LST码一手
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e6+100;
const int INF = 0x3f3f3f3f;
int dp[maxn]; //dp数组维护一个最长上升子序列长度 严格单调递增1,3,5不能是1 3 3
int a[maxn];

//template<typename T>
//void read(T &x){
//    x = 0;
//    char ch = getchar();
//    for(;ch<'0'||ch>'9';ch=getchar());
//    for(;ch>='0'&&ch<='9';ch=getchar()) x = x*10+ch-'0';
//}
//加快读入速度
int main(){
    int n;
    while(~scanf("%d",&n)){
        for(int i=1;i<=n;++i){
            scanf("%d",a+i);
//            read(a[i]);
            dp[i] = INF;
        }
        dp[1] = a[1];
        int len = 1;
        for(int i=2;i<=n;++i){

            if(a[i]>dp[len]){
                dp[++len] = a[i];
            }
            else{
                    dp[lower_bound(dp+1,dp+len+1,a[i])-dp]=a[i];//防止之后有比之前的更长的序列。不断更新dp
                    //lower_bound(首地址+1,末地址+1,插入元素)找到第一个>=a[i]的数字返回其地址,-首地址则得到下标
                    //只维护长度。输出序列非最长上升子序列
                    //等同于下面的二分查找
//                int l=1,r=len,mid;
//                while(l<=r){
//                    mid = (l+r)>>1;
//                    if(a[i]>dp[mid]) l = mid+1;
//                    else r = mid-1;
//                }
//                dp[l] = a[i]; //在l~len区间内二分查找dp数组中大于a[i]的第一个元素的位置并插入
            }
        }
//	debug检查dp数组维护的子序列
	for(int i=1;i<=len;++i){
            printf("%d ",dp[i]);
        }
        puts("");
    int pos = 1;
    for(int i=n;i>=1;--i){
        if(a[i]==dp[len]){
            pos = i; break;
        }
    }
//    int cnt = 1,last = dp[len];
//    printf("%d%c",dp[len],(cnt==len)?'\n':' ');
//    for(int i=pos-1;i>=1;--i){
//        if(a[i]<last){
//            last = a[i];
//            ++cnt;
//            printf("%d%c",a[i],(cnt==len)?'\n':' ');
//        }
//    }
        printf("%d\n",len);
    }
    return 0;
}

//最长单调不升子序列 这个可以是1 1 1 1 / 3 2 1并非严格的递减
//#include<bits/stdc++.h>
//using namespace std;
//const int maxn = 1e6+100;
//const int INF = 0x3f3f3f3f;
//int dp[maxn];
//int a[maxn];
//
//template<typename T>
//void read(T &x){
//    x = 0;
//    char ch = getchar();
//    for(;ch<'0'||ch>'9';ch=getchar());
//    for(;ch>='0'&&ch<='9';ch=getchar()) x = x*10+ch-'0';
//}
//
//int main(){
//    int n;
//    while(~scanf("%d",&n)){
//        for(int i=1;i<=n;++i){
//            scanf("%d",a+i);
//            read(a[i]);
//            dp[i] = -INF; //赋值-INF与LST有所不同
//        }
//        dp[1] = a[1];
//        int len = 1;
//        for(int i=2;i<=n;++i){
//            if(a[i]<=dp[len]){ //LST 中 > 改为 <=
//                dp[++len] = a[i];
//            }
//            else{
//                int l=1,r=len,mid;
//                while(l<=r){
//                    mid = (l+r)>>1;
//                    if(a[i]<dp[mid]) l = mid+1; //把LST中的>改为<即可
//                    else r = mid-1;
//                }
//                dp[l] = a[i];
//            }
//        }
//        printf("%d\n",len);
//    }
//    return 0;
//}
//

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值