/*首先用f[i]表示从i开始的最长上升子序列的长度(注意这里和平时的不一样,是以i开头而不是以1到i)
这就相当于倒序做一遍最长下降子序列
然后要用到贪心
首先假设要取长度为x的,如果比算出来的max大(max正序倒序都一样的),肯定无解
然后从头开始取,因为从头取的下标字典序最小,如果a[i]比上一个取的last大,并且f[i]>=当前的x,
那么a[i]可以取,然后last=a[i],x--,一直这样做下去*/
#include<cstdio>
#include<cstdlib>
using namespace std;
int a[10002],b[10002];
int f[10002],fi[10002];
int n,maxx,M,x;
void get_prelis(){
f[1]=1;
for(int i=2;i<=n;++i)
for(int j=1;j<=i;++j){
if(b[i]<b[j]&&f[i]<f[j]+1) {
f[i]=f[j]+1;
if(f[i]>maxx) maxx=f[i];
}
}
for(int i=1;i<=n;++i) fi[i]=f[n-i+1];
}
void getlis(int p){
int last=0;
for(int i=1;i<=n;++i){
if(fi[i]>=p&&a[i]>last&&p){
printf("%d",a[i]);
if(p!=1) printf(" ");
last=a[i];
p--;
}
}
printf("\n");
}
int main(){
freopen("lis.in","r",stdin);
freopen("lis.ans","w",stdout);
scanf("%d",&n);
for(int i=1;i<=n;++i) {
scanf("%d",&a[i]);
b[n-i+1]=a[i];
}
get_prelis();
scanf("%d",&M);
for(int op=1;op<=M;++op){
scanf("%d",&x);
if(x>maxx) printf("Impossible\n");
else
getlis(x);
}
}
bzoj 1046: [HAOI2007]上升序列
最新推荐文章于 2019-08-09 14:56:00 发布