考虑一个长度为 (L) 的最长上升子序列 (P),以它的第 (i) 个元素 (a_{x_i}) 为开头的最长上升子序列长度必定不小于 (L-i+1)。反之,若一个数满足以其为开头的最长上升子序列长度不小于 (L-i+1) 则这个数必定可以作为 (P) 的第 (i) 个元素。
所以我们可以先倒着跑一遍最长下降子序列,求出以每个数为开头的最长上升子序列。接着贪心地考虑,从前往后扫能取就取,显然最优。
时间复杂度 (O(N^2))。
code:
#include<bits/stdc++.h>
using namespace std;
#define N 10005
#define Max(x,y)((x)>(y)?x:y)
#define For(i,x,y)for(i=x;i<=(y);i++)
#define Down(i,x,y)for(i=x;i>=(y);i--)
int f[N],b[N],a[N];
void write(int X)
{
if(X<0)putchar('-'),X=-X;
if(X>9)write(X/10);
putchar(X%10|48);
}
int main()
{
int n,i,j,m,l,top;
scanf("%d",&n);
For(i,1,n)scanf("%d",&a[i]);
a[n+1]=INT_MAX;
Down(i,n,1)
For(j,i+1,n+1)
if(a[j]>a[i])f[i]=Max(f[i],f[j]+1);
scanf("%d",&m);
while(m--)
{
scanf("%d",&l);
top=l;
b[l+1]=INT_MIN;
For(i,1,n)
if(top&&f[i]>=top&&a[i]>b[top+1])b[top--]=a[i];
if(top)
{
puts("Impossible");
continue;
}
Down(i,l,1)write(b[i]),putchar(' ');
putchar('
');
}
return 0;
}