不知道什么印象,好像以前见过,记得要把数列倒过来的~
nlogn的最长上升子序列。
但是方案不好搞~
PS:看好是谁的字典序最小。。。
换个问题,
假设知道以a[i]为开头的最长下降子序列的长度,是不是就好搞了?
方法是从左往右,直接贪心的选这个i(以a[i]为开头的最长下降子序列的长度要大于你需要的长度)一定是能使字典序最小~
前面说了,倒过来做就行了, 因为我们只会求以a[i]结尾的最长上升子序列的长度。。。
View Code
1 #include2 #include 3 #include 4 #include 5 #include 6 7 #define N 111111 8 #define INF 0x3f3f3f3f 9 #define BUG system("pause")10 11 using namespace std;12 13 int n,a[N],b[N],dp[N];14 int len,stk[N],p,cas,m;15 16 inline void read()17 {18 scanf("%d",&n);19 for(int i=n;i>=1;i--) scanf("%d",&a[i]);20 }21 22 inline void step1()23 {24 len=1;25 for(int i=0;i<=n;i++) b[i]=-INF;26 b[0]=INF; b[1]=a[1]; dp[1]=1;27 for(int i=2;i<=n;i++)28 {29 int l=0,r=len+1,mid,res;30 while(l<=r)31 {32 mid=(l+r)>>1;33 if(b[mid]>a[i]) res=mid,l=mid+1;34 else r=mid-1;35 }36 len=max(res+1,len);37 b[res+1]=max(b[res+1],a[i]);38 dp[i]=res+1;39 }40 reverse(a+1,a+1+n);41 reverse(dp+1,dp+1+n);42 }43 44 inline void step2()45 {46 if(len =m&&a[i]>last) stk[++p]=i,m--,last=a[i];51 for(int i=1;i