#include<iostream>
#include<stdio.h>
#include<stack>
using namespace std;
int a[20005],d[20005];//a存放数组,d存放逆序的元素个数
/*
例如a数组为 3 4 1 2 3 6
d数组中存储为 3 2 4 3 2 1
*/
void main()
{
int i,j;
int n,m,length;
scanf("%d",&n);//输入数组大小n
for (i=1;i<=n;i++)
{
scanf("%d",&a[i]);//输入数据
}
scanf("%d",&m);//输入要查询m组序列
for(i=n;i>=1;i--)
{
d[i]=1;
for(j=n;j>i;j--)
{
if(a[i]<a[j] && d[i]<d[j]+1)
d[i]=d[j]+1;//动态规划思想,求最长降序(逆序,降序)
}
}
while(m--)
{
int temp=INT_MIN;
int flag=0;
scanf("%d",&length);
for(i=1;i<=n;i++)
{
if(length<=d[i])
{
flag=1;
break;
}
}
if(flag==0)
printf("Impossible\n");
else
{
i=1;
while(i<=n && length)
{
//当要查询的长度小于该数起始的数组长度时,并且后面的数要大于前面的数
//才能保证升序,每次输出一个数后length-1.
/*
对于有解的情形 设要求的长度为len
从头找到第一个使得d[i]>=len的i,这就是符合要求的LIS的第一个数;
在i之后找到第一个使得d[j]>=len-1且a[j]>a[i]的j,这就是第二个数;
在j之后找到第一个使得d[k]>=len-2且a[k]>a[j]的k,这就是第三个数;
…… 依此类推
*/
if(length<=d[i] && a[i]>temp )
{
printf("%d ",a[i]);
length--;
temp=a[i];
}
i++;
}
printf("\n");
}
}
system("pause");
}
ps.可以通过二分查找改进效率 达到O(nlogn)