题目链接:
题意:给出一个长度为n的数列。输出数列一个长度恰好为m的下标字典序最小的(即最靠左的)上升子列。
思路:从右向左求一次最长递减子列,记录每个位置的f值,即以该数结尾最长的下降子列。对于给定的m,先从左向右找到一个f[i]>=m的位置,那么这个数肯定是答案的第一个,输出它,然后向右找一个大于这个数且f[j]>=m-1的数输出,依依次类推。。。
#include#include using namespace std; const int MAX=100005; int C,num=0; int n,Q,m,f[MAX],cNum,c[MAX],a[MAX]; void DP() { int i,mid,low,high; cNum=0;c[++cNum]=a[1];f[1]=1; for(i=2;i<=n;i++) { low=1;high=cNum+1; while(low >1; if(a[i] =1;i--) if(f[i]>=m) { printf("%d",a[i]); m--; pre=a[i]; break; } while(m) { while(a[--i]>pre&&f[i]>=m) { printf(" %d",a[i]); m--; pre=a[i]; break; } } puts(""); } int main() { for(scanf("%d",&C);C--;) { scanf("%d%d",&n,&Q); int i; for(i=1;i<=n;i++) scanf("%d",&a[n+1-i]); DP(); printf("Case %d:\n",++num); while(Q--) { scanf("%d",&m); if(m>cNum) { puts("Impossible"); continue; } deal(); } } return 0; }