BZOJ1046 [HAOI2007]上升序列
Description
对于一个给定的S={a1,a2,a3,…,an},若有P={ax1,ax2,ax3,…,axm},满足(x1 < x2 < … < xm)且( ax1 < ax
2 < … < 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
3 4 1 2 3 6
3
6
4
5
Sample Output
1 2 3 6
Impossible
解题报告:
其实挺水的却花了我半个多小时。
显然先DP做最长上升子序列,然后做贪心。显然从前往后扫,每次扫到第一个发现长度大于要求长度,且当前值>last的就输出,然后长度--,last=当前值。这样贪心应该是正确的。
我WA了两发,因为当长度变成0时应该及时跳出,而不是往后做。
然后我还学了一下nlogn的最长上升子序列的DP,思想也很简单,就是从后往前做,然后维护每种长度当前的开始的结点的值最大值,对于每个i都二分查找出它之后可以接的最大长度。这显然是nlogn的。
n^2 的做法:
//It is made by jump~
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <ctime>
#include <vector>
#include <queue>
#include <map>
#include <set>
#ifdef WIN32
#define OT "%I64d"
#else
#define OT "%lld"
#endif
using namespace std;
typedef long long LL;
const int MAXN = ;
const int inf = (<<);
int n,m,maxl;
int a[MAXN],f[MAXN]; inline int getint()
{
int w=,q=;
char c=getchar();
while((c<'' || c>'') && c!='-') c=getchar();
if (c=='-') q=, c=getchar();
while (c>='' && c<='') w=w*+c-'', c=getchar();
return q ? -w : w;
} inline void work(){
n=getint(); for(int i=;i<=n;i++) a[i]=getint(),f[i]=;
int len;
for(int i=n-;i>=;i--) {//事实上可以nlogn做最长上升子序列,记录每种长度的出现的最大的值,然后二分查找找到能够匹配的最大长度值
len=;
for(int j=i+;j<=n;j++) {
if(a[j]>a[i] && f[j]>=len) len=f[j];
}
f[i]=len+; maxl=max(f[i],maxl);
}
m=getint(); int x,last;
for(int o=;o<=m;o++) {//实际上这里不能直接输出,应该不断往后找可行解
if(o>) printf("\n");
x=getint(); last=-inf;
if(maxl<x) { printf("Impossible"); continue; }
for(int i=;i<=n;i++) {
if(f[i]>=x && a[i]>last) {
if(last!=-inf) printf(" ");
last=a[i]; x--;
printf("%d",a[i]);
if(!x) break;//及时跳出
}
}
}
} int main()
{
work();
return ;
}
nlogn的做法:
//It is made by jump~
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <ctime>
#include <vector>
#include <queue>
#include <map>
#include <set>
#ifdef WIN32
#define OT "%I64d"
#else
#define OT "%lld"
#endif
using namespace std;
typedef long long LL;
const int MAXN = ;
const int inf = (<<);
int n,m;
int a[MAXN],f[MAXN],c[MAXN];//c[i]表示长度为i的开始结点的值的最大值
int maxl; inline int getint()
{
int w=,q=;
char c=getchar();
while((c<'' || c>'') && c!='-') c=getchar();
if (c=='-') q=, c=getchar();
while (c>='' && c<='') w=w*+c-'', c=getchar();
return q ? -w : w;
} inline int search(int x){//二分查找
int l=,r=maxl,mid; int pos;
while(l<=r) {
mid=(l+r)>>;
if(c[mid]>x) pos=mid,l=mid+;
else r=mid-;
}
return pos;
} inline void work(){
n=getint(); for(int i=;i<=n;i++) a[i]=getint();
int now; c[]=inf;
for(int i=n;i>=;i--) {//倒着查找
now=search(a[i]); f[i]=now+;
c[f[i]]=max(c[f[i]],a[i]);
maxl=max(maxl,f[i]);
}
m=getint(); int last;
for(int o=;o<=m;o++) {
if(o!=) printf("\n");
now=getint(); last=-inf;
if(now>maxl) { printf("Impossible"); continue; }
for(int i=;i<=n;i++){
if(f[i]>=now && a[i]>last) {
printf("%d",a[i]);
if(now!=) printf(" "); else break;//记得及时退出
now--; last=a[i];
}
}
}
} int main()
{
work();
return ;
}
BZOJ1046 [HAOI2007]上升序列的更多相关文章
- BZOJ1046 [HAOI2007]上升序列 【LIS + 字典序最小】
1046: [HAOI2007]上升序列 Time Limit: 10 Sec Memory Limit: 162 MB Submit: 5410 Solved: 1877 [Submit][St ...
- 2014.8.15模拟赛【公主的工作】&&bzoj1046[HAOI2007]上升序列
bzoj题目是这样的 Description 对于一个给定的S={a1,a2,a3,…,an},若有P={ax1,ax2,ax3,…,axm},满足(x1 < x2 < … < xm ...
- [BZOJ1046] [HAOI2007] 上升序列 (dp)
Description 对于一个给定的S={a1,a2,a3,…,an},若有P={ax1,ax2,ax3,…,axm},满足(x1 < x2 < … < xm)且( ax1 < ...
- 【动态规划】【最长上升子序列】【贪心】bzoj1046 [HAOI2007]上升序列
nlogn求出最长上升子序列长度. 对每次询问,贪心地回答.设输入为x.当前数a[i]可能成为答案序列中的第k个,则若 f[i]>=x-k && a[i]>ans[k-1] ...
- BZOJ1046: [HAOI2007]上升序列(LIS)
Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 5740 Solved: 2025[Submit][Status][Discuss] Descript ...
- bzoj1046 [HAOI2007]上升序列——LIS
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1046 倒序求最长下降子序列,则得到了每个点开始的最长上升子序列: 然后贪心输出即可. 代码如 ...
- [BZOJ1046][HAOI2007]上升序列 DP+贪心
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1046 我们先求出对于每一个数字作为开头的LCS的长度f[i],最长的f[i]为mxlen. ...
- 【BZOJ1046】[HAOI2007]上升序列
[BZOJ1046][HAOI2007]上升序列 题面 bzoj 洛谷 题解 \(dp\)完之后随便搞一下即可,注意不要看错题 代码 #include <iostream> #includ ...
- 【BZOJ-1046】上升序列 DP + 贪心
1046: [HAOI2007]上升序列 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 3723 Solved: 1271[Submit][Stat ...
随机推荐
- maven总结4
仓库.nexus 构件:在maven中,任何一个依赖(jar包).插件(maven-compiler-plugin-2.5.1.jar)或者项目输出(前面例子中运行mvn clean install ...
- Java AtomicInteger
AtomicInteger,一个提供原子操作的Integer的类.在Java语言中,++i和i++操作并不是线程安全的,在使用的时候,不可避免的会用到synchronized关键字.而AtomicIn ...
- Spring 集成 RMI
Maven <dependency> <groupId>org.springframework</groupId> <artifactId>spring ...
- 你会在C#的类库中添加web service引用吗?
本文并不是什么高深的文章,只是VS2008应用中的一小部分,但小部分你不一定会,要不你试试: 本人对于分布式开发应用的并不多,这次正好有一个项目要应用web service,我的开发环境是vs2008 ...
- The Linux Storage Stack Diagram
相关文章: 如何提高Linux下块设备IO的整体性能?
- Python高手之路【八】python基础之requests模块
1.Requests模块说明 Requests 是使用 Apache2 Licensed 许可证的 HTTP 库.用 Python 编写,真正的为人类着想. Python 标准库中的 urllib2 ...
- Linux内核启动
Linux内核启动过程概述 Linux的启动代码真的挺大,从汇编到C,从Makefile到LDS文件,需要理解的东西很多.毕竟Linux内核是由很多人,花费了巨大的时间和精力写出来的.而且直到现在,这 ...
- Sql Server UniCode编码解码
); set @s = N'揶'; select UniCode(@s),nchar(UniCode(@s)); 在 SQL Server 中处理 Unicode 字串常数时,您必需在所有的 Unic ...
- ZooKeeper学习第六期---ZooKeeper机制架构
一.ZooKeeper权限管理机制 1.1 权限管理ACL(Access Control List) ZooKeeper 的权限管理亦即ACL 控制功能,使用ACL来对Znode进行访问控制.ACL的 ...
- Fork一个仓库
Fork 是对一个仓库的克隆.克隆一个仓库允许你自由试验各种改变,而不影响原始的项目. 一般来说,forks 被用于去更改别人的项目(贡献代码给已经开源的项目)或者使用别人的项目作为你自己想法的初始开 ...