码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj 1046

时间:2017-10-24 20:50:15      阅读:154      评论:0      收藏:0      [点我收藏+]

标签:数组   sdi   char   for   void   etc   type   ret   ssi   

一看就知道是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;
}

 

bzoj 1046

标签:数组   sdi   char   for   void   etc   type   ret   ssi   

原文地址:http://www.cnblogs.com/oris71/p/7725355.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!