bzoj 1046: [HAOI2007]上升序列

/*首先用f[i]表示从i开始的最长上升子序列的长度(注意这里和平时的不一样,是以i开头而不是以1到i)
这就相当于倒序做一遍最长下降子序列
然后要用到贪心
首先假设要取长度为x的,如果比算出来的max大(max正序倒序都一样的),肯定无解
然后从头开始取,因为从头取的下标字典序最小,如果a[i]比上一个取的last大,并且f[i]>=当前的x,
那么a[i]可以取,然后last=a[i],x--,一直这样做下去*/
#include
#include
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]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]上升序列)