题解: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;
}