BZOJ 1046: [HAOI2007]上升序列(LIS)
题目挺坑的..但是不难.先反向做一次最长下降子序列.然后得到了d(i),以i为起点的最长上升子序列,接下来贪心,得到字典序最小.
-------------------------------------------------------------------
#include<cstdio>#define rep(i,n) for(int i=0;i<n;++i)using namespace std;const int maxn=10005;const int inf=0x7fffffff;int a[maxn];int g[maxn];int d[maxn];int lowerBound(int l,int r,int v) {int mid;while(l<r) {mid=l+(r-l)/2;if(g[mid]<=v) r=mid;else l=mid+1;}return l;}int main(){freopen("test.in","r",stdin);freopen("test.out","w",stdout);int n,m;scanf("%d",&n);rep(i,n) { scanf("%d",&a[i]); g[i+1]=-inf; }for(int i=n-1;i>=0;--i) {int k=lowerBound(1,n,a[i]);d[i]=k;g[k]=a[i];}scanf("%d",&m);while(m--) {int l;scanf("%d",&l);if(g[l]==-inf) printf("Impossible");else {int last=-inf;rep(i,n) if(d[i]>=l && a[i]>last) {printf("%d",a[i]);if(0==--l) break;last=a[i];printf(" ");}}printf("\n");}return 0;}--------------------------------------------------------------------
1046: [HAOI2007]上升序列
Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 2843 Solved: 949
[Submit][Status][Discuss]
Description
对于一个给定的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.
Input
第一行一个N,表示序列一共有N个元素第二行N个数,为a1,a2,…,an 第三行一个M,表示询问次数。下面接M行每行一个数L,表示要询问长度为L的上升序列。
Output
对于每个询问,如果对应的序列存在,则输出,否则打印Impossible.
Sample Input
63 4 1 2 3 6
3
6
4
5
Sample Output
Impossible1 2 3 6
Impossible
HINT
数据范围
N<=10000
M<=1000
转载于:https://www.cnblogs.com/JSZX11556/p/4374561.html
总结
以上是生活随笔为你收集整理的BZOJ 1046: [HAOI2007]上升序列(LIS)的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: destoon实现调用热门关键字的方法
- 下一篇: HDU2612 Find a Way B