//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;
//}
//
LST最长上升子序列 和非升序序列
最新推荐文章于 2024-08-10 19:35:28 发布