Ah, noip difficulty question... I spent half a day in the workshop...
Well, first we need to find the LIS length.
Then we are greedy. Suppose we have found the X item of the answer, and then find the x + 1 item backward:
We found that you only need to find the first a [I] that meets f [I]> = l-x.
1 /************************************************************** 2 Problem: 1046 3 User: rausen 4 Language: C++ 5 Result: Accepted 6 Time:1772 ms 7 Memory:960 kb 8 ****************************************************************/ 9 10 #include <cstdio>11 #include <algorithm>12 13 using namespace std;14 const int N = 10005;15 const int inf = (int) 1e9;16 int f[N], a[N], b[N];17 int len, n;18 int ans[N];19 20 inline int read(){21 int x = 0, sgn = 1;22 char ch = getchar();23 while (ch < ‘0‘ || ch > ‘9‘){24 if (ch == ‘-‘) sgn = -1;25 ch = getchar();26 }27 while (ch >= ‘0‘ && ch <= ‘9‘){28 x = x * 10 + ch - ‘0‘;29 ch = getchar();30 }31 return sgn * x;32 }33 34 void pre_work(){35 len = 1;36 int l, r, mid;37 for (int i = 2; i <= n; ++i)38 b[i] = -inf;39 b[0]= inf, b[1] = a[1], f[1] = 1;40 for (int i = 2; i <= n; ++i){41 l = 0, r = len + 1;42 while (l + 1 < r){43 mid = (l + r) >> 1;44 if (b[mid] > a[i]) l = mid;45 else r = mid;46 }47 len = max(len, ++l);48 b[l] = max(b[l], a[i]);49 f[i] = l;50 }51 reverse(a + 1, a + n + 1);52 reverse(f + 1, f + n + 1);53 }54 55 void work(int l){56 if (len < l){57 printf("Impossible\n");58 return;59 }60 int cnt = 0, last = -inf;61 for (int i = 1; i <= n && l != 0; ++i)62 if (f[i] >= l && a[i] > last)63 ans[++cnt] = i, --l, last = a[i];64 for (int i = 1; i < cnt; ++i)65 printf("%d ", a[ans[i]]);66 printf("%d\n", a[ans[cnt]]);67 }68 69 int main(){70 n = read();71 for (int i = n; i; --i)72 a[i] = read();73 pre_work();74 int m = read(), X;75 while (m--){76 X = read();77 work(X);78 }79 return 0;80 }View code
Bzoj1046 [haoi2007] ascending sequence