最长上升子序列贪心优化版本+输出最小字典序方案
//时间复杂度分析:O(nlogn)
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1e5+10;
int f[N];
int a[N];
int dp[N];
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
int len=0;
for(int i=1;i<=n;i++)
{
int l=0,r=len;
while(l<r)
{
int mid=l+r+1>>1;
if(f[mid]<a[i]) l=mid;
else r=mid-1;
}
dp[i]=l+1;//这个一定是长度为l+1 结尾最小的那个元素
//因为它小于等于所有的长度为l+1的元素才会有这个
len=max(len,l+1);
f[l+1]=a[i];
}
cout<<len<<endl;
vector<int>ans(len);
for(int i=n;i>=1;i--)
{
if(dp[i]==len)
{
ans[--len]=a[i];
}
}
for(int i=0;i<ans.size();i++)
{
cout<<ans[i]<<' ';
}
}