题解:f[i]表示以i开头的最长上升子序列长度
贪心先选下标最小的符合要求的元素
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn=10009; int n,T; int maxlen; int a[maxn]; int b[maxn],nn; int c[maxn]; int lowbit(int x){ return x&(-x); } void Addp(int x,int val){ while(x<=nn){ c[x]=max(c[x],val); x+=lowbit(x); } } int Querymax(int x){ int ret=0; while(x){ ret=max(ret,c[x]); x-=lowbit(x); } return ret; } int f[maxn]; int main(){ scanf("%d",&n); for(int i=1;i<=n;++i){ scanf("%d",&a[i]); a[i]=b[i]=-a[i]; } sort(b+1,b+1+n); nn=unique(b+1,b+1+n)-b-1; for(int i=1;i<=n;++i)a[i]=lower_bound(b+1,b+1+nn,a[i])-b; for(int i=n;i>=1;--i){ f[i]=Querymax(a[i]-1)+1; maxlen=max(maxlen,f[i]); Addp(a[i],f[i]); } scanf("%d",&T); while(T--){ int l; scanf("%d",&l); if(l>maxlen){ printf("Impossible\n"); }else{ int now=-0x7fffffff; for(int i=1;i<=n;++i){ if((-b[a[i]]>now)&&(f[i]>=l)){ printf("%d",-b[a[i]]); if(l!=1)printf(" "); now=-b[a[i]]; if(--l==0)break; } } if(T)printf("\n"); } } return 0; }