[bzoj1046]上升序列

以i为开头的最长上升子序列,那么就是反过来以i为结尾的最长下降子序列,预处理出来后,不断向后找到下一个数即可

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define N 10005
 4 int n,m,x,a[N],b[N],f[N];
 5 int find(int k){
 6     int l=0,r=b[0];
 7     while (l<r){
 8         int mid=(l+r+1>>1);
 9         if (b[mid]>k)l=mid;
10         else r=mid-1;
11     }
12     return l;
13 }
14 int main(){
15     scanf("%d",&n);
16     for(int i=1;i<=n;i++)scanf("%d",&a[i]);
17     for(int i=n;i;i--){
18         f[i]=find(a[i])+1;
19         b[0]=max(b[0],f[i]);
20         b[f[i]]=max(b[f[i]],a[i]);
21     }
22     scanf("%d",&m);
23     for(int i=1;i<=m;i++){
24         scanf("%d",&x);
25         if (x>b[0])printf("Impossible
");
26         else{
27             int last=0;
28             for(int j=1;j<=n;j++){
29                 if ((f[j]>=x)&&(a[j]>last)){
30                     printf("%d ",last=a[j]);
31                     if (!--x)break;
32                 }
33             }
34             printf("
");
35         }
36     }
37 }
View Code
原文地址:https://www.cnblogs.com/PYWBKTDA/p/11765623.html