bzoj 1046

一看就知道是DP了。

注意要求字典序最小,所以要从后往前做最长下降子序列。

如果不加二分或者树状数组之类的优化应该会TLE的吧。

输出的时候找一下答案即可。

#include<cstdio>
#include<cctype>
#include<algorithm>
using namespace std;
int read(){
    char c; while(!isdigit(c=getchar()) && c!='-');
    int x=0,y=1; if(c=='-') y=-1; else x=c-'0';
    while(isdigit(c=getchar())) x=x*10+c-'0'; return x*y;
}
int a[10001],f[10001],w[10001];
int find(int l,int r,int v){
    while(l<=r){
        int mid=l+r>>1;
        if(v<w[mid]) l=mid+1;
        else r=mid-1;
    }
    return l;
}
void print(int n,int l){
    int pre=-2e9,fs=0;
    for(int i=1;i<=n && l;i+=1)
        if(pre<a[i] && f[i]>=l){
            if(!fs) fs=1,printf("%d",a[i]);
            else printf(" %d",a[i]);
            pre=a[i]; l--;
        }
    printf("\n");
}
int main(){
    int n=read(),m=0;
    for(int i=1;i<=n;i+=1) a[i]=read();
    for(int i=n;i>=1;i-=1){
        f[i]=find(1,m,a[i]);
        if(m<f[i]) w[++m]=a[i];
        else w[f[i]]=max(w[f[i]],a[i]);
    }
    int q=read();
    while(q--){
        int l=read();
        if(l<1 || l>m) puts("Impossible");
        else print(n,l);
    }
    return 0;
}

 

posted @ 2017-10-24 19:41  或是七一  阅读(86)  评论(0编辑  收藏  举报