[HAOI2007] 上升序列

【问题描述】

 对于一个给定的S={a1,a2,a3,…,an},若有P={ax1,ax2,ax3,…,axm},满足(x1<x2<…<xm)且(ax1<ax2<…<axm)。那么就称P为S的一个上升序列。如果有多个P满足条件,那么我们想求字典序最小的那个。 任务 给出S序列,给出若干询问。对于第i个询问,求出长度为Li的上升序列,如有多个,求出字典序最小的那个(即首先x1最小,如果不唯一,再看x2最小……),如果不存在长度为Li的上升序列,则打印Impossible.

【输入格式】 
  第一行一个N,表示序列一共有N个元素

第二行N个数,为a1,a2,…,an

第三行一个M,表示询问次数。下面接M行每行一个数L,表示要询问长度为L的上升序列。

【输出格式】 
对于每个询问,如果对应的序列存在,则输出,否则打印Impossible.

【输入样例】 
6
3 4 1 2 3 6
3
6
4
5


【输出样例】 
Impossible
1 2 3 6
Impossible

【数据范围】

N<=10000 M<=1000

 

 

 

最长下降,贪心。蛮难的。一开始理解错了题目意思。

 1 #include<iostream>
 2 #include<fstream>
 3 //#define fout cout
 4 using namespace std;
 5 ifstream fin("lis.in");
 6 ofstream fout("lis.out");
 7 
 8 int n,m,a[10005]={0},b[10005],c[10005],len=0;
 9 
10 int Erfen(int x){
11     int l=1,r=len,mid;
12     while(l<=r)
13     {
14       mid=(l+r)>>1;
15       if(c[mid]==x) return mid;
16       else if(c[mid]<x) r=mid-1;
17       else l=mid+1;
18               }
19     return l;
20     }
21 
22 int main()
23 {
24     fin>>n;
25     
26     for(int i=1;i<=n;++i) fin>>a[i];
27     
28     for(int i=n;i>=1;--i)
29     {
30       int l=Erfen(a[i]);
31       if(l>len) len++;
32       c[l]=a[i];
33       b[i]=l;
34             }
35 
36     fin>>m;
37     for(int i=1;i<=m;++i)
38     {
39       int x,j;
40       fin>>x;
41       for(j=1;j<=n;++j)
42       if(b[j]>=x) break;
43       if(j>n) {fout<<"Impossible"<<endl;continue;}
44       int tot=1,last=0;
45       for(j;j<=n;++j)
46       if(a[j]>a[last]&&b[j]>x-tot) {if(tot<x) fout<<a[j]<<" ";else {fout<<a[j]<<endl;break;}last=j;tot++;}
47             }
48    // system("pause");
49     return 0;
50     
51     }

 

posted on 2012-10-30 01:17  怡红公子  阅读(372)  评论(0编辑  收藏  举报