BZOJ 1046: [HAOI2007]上升序列【贪心+二分状态+dp+递归】
2017-08-08 09:29
465 查看
1046: [HAOI2007]上升序列
Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 4987 Solved: 1732
[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的上升序列。N<=10000,M<=1000
Output
对于每个询问,如果对应的序列存在,则输出,否则打印Impossible.Sample Input
63 4 1 2 3 6
3
6
4
5
Sample Output
Impossible1 2 3 6
Impossible
HINT
Source
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1046分析:首先求出以每个数为开头上升序列长度,即倒着做最长下降子序列
然后,把字典序尽量小的放前面
即若要求的序列长度为x,如果以第一个数(字典序最小的数)开头的最长上升子序列大等于x,则将它放在答案第一个,第二个数开头小于x,则舍弃,第三个大于x-1,放答案第二个,以此类推!
下面给出AC代码:
#include <bits/stdc++.h> using namespace std; inline int read() { int x=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar(); } while(ch>='0'&&ch<='9') { x=x*10+ch-'0'; ch=getchar(); } return x*f; } int n,m,cnt; const int N=100010; int a ,f ,best ; inline void solve(int x) { int last=0; for(int i=1;i<=n;i++) { if(f[i]>=x&&a[i]>last) { printf("%d",a[i]); if(x!=1) printf(" "); last=a[i]; if(!(--x)) break; } } printf("\n"); } inline int find(int x) { int l=1,r=cnt,ans=0; while(l<=r) { int mid=(l+r)/2; if(best[mid]>x) ans=mid,l=mid+1; else r=mid-1; } return ans; } inline void pre() { for(int i=n;i;i--) { int t=find(a[i]); f[i]=t+1; cnt=max(cnt,t+1); if(best[t+1]<a[i]) best[t+1]=a[i]; } } int main() { n=read(); for(int i=1;i<=n;i++) a[i]=read(); pre(); m=read(); for(int i=1;i<=m;i++) { int x=read(); if(x<=cnt) solve(x); else printf("Impossible\n"); } return 0; }
相关文章推荐
- Bzoj 1046: [HAOI2007]上升序列 二分,递推
- BZOJ 1046 HAOI 2007 上升序列 -- DP 贪心
- BZOJ 1046: [HAOI2007]上升序列 暴力,二分
- BZOJ 1046([HAOI2007]上升序列-LIS二分O(nlogn))
- BZOJ 1046 [HAOI2007]上升序列 动态规划+贪心
- bzoj 1046: [HAOI2007]上升序列【dp+二分】
- [BZOJ1046][HAOI2007]上升序列(dp+贪心)
- 【动态规划】【最长上升子序列】【贪心】bzoj1046 [HAOI2007]上升序列
- BZOJ1046 [HAOI2007]上升序列 【LIS + 字典序最小】
- bzoj 1046: [HAOI2007]上升序列 解题报告
- bzoj 1046 [HAOI2007] 上升序列 题解
- 2014.8.15模拟赛【公主的工作】&&bzoj1046[HAOI2007]上升序列
- 【BZOJ 1046】 [HAOI2007]上升序列
- bzoj1046: [HAOI2007]上升序列
- 【BZOJ1046】 [HAOI2007]上升序列
- 2014.8.15模拟赛【公主的工作】&&bzoj1046[HAOI2007]上升序列
- [BZOJ1046][HAOI2007]上升序列
- BZOJ1046: [HAOI2007]上升序列
- [BZOJ 1046][HAOI 2007]上升序列(nlogn的LIS算法)
- BZOJ 1046: [HAOI2007]上升序列