bzoj 1046 LIS
假设我们知道以每个点开始到最后的最长上升序列,设为w[i],这样首先我们在w值中取max,如果询问的值比max大,这样显然就是无解,如果小的话,我们需要求出来字典序最小的方案。
那么对于所有i,我们肯定以w[i]大于询问的值中的最小的i开始,那么假设上升序列中第一个值为i,第二个值为j,那么w[j]满足大于询问的值-1,且初始序列a中,a[j]的值要大于a[i],且为最小的j,对于最小的我们只需要通过循环正常的枚举就行了。
那么我们现在剩下的问题就是w[i]值如何求,如果n小一些的话我们就可以n^2正常的做了,但是n为10^4,这样我们就需要维护单调队列que[i],表示长度为i的最长上升序列中,结尾最小的值,这样就可以了。但是我们要求每个w的话需要反向枚举,然后维护下降序列就可以了。
/**************************************************************
Problem: 1046
User: BLADEVIL
Language: C++
Result: Accepted
Time:2088 ms
Memory:924 kb
****************************************************************/ //By BLADEVIL
#include <cstdio>
#define maxn 10010
#define inf 20000 using namespace std; int n,tot;
int a[maxn],w[maxn],que[maxn]; int combin(int x)
{
int l,r,mid,ans=;
l=; r=tot;
while (l<=r)
{
mid=(l+r)>>;
if (que[mid]>x)
{
ans=mid;
l=mid+;
} else r=mid-;
}
return ans;
} int main()
{
scanf("%d",&n);
for (int i=;i<=n;i++) scanf("%d",&a[i]);
tot=;
for (int i=n;i;i--)
{
w[i]=combin(a[i]);
//printf("%d %d|",w[i],tot);
if (w[i]++==tot) tot++;
que[w[i]]=(a[i]>que[w[i]])?a[i]:que[w[i]];
//for (int j=1;j<=tot;j++) printf("%d ",que[j]); printf("\n");
}
int maxlen=;
for (int i=;i<=n;i++) maxlen=(w[i]>maxlen)?w[i]:maxlen;
//for (int i=1;i<=n;i++) printf("%d ",w[i]); printf("\n");
int m;
scanf("%d",&m);
while (m--)
{
int len;
scanf("%d",&len);
if (len>maxlen)
{
printf("Impossible\n");
continue;
}
int last=-inf;
for (int i=;i<=n;i++)
if (w[i]>=len&&a[i]>last)
{
printf("%d",a[i]);
if (len==)
{
printf("\n");
break;
} else
printf(" "),last=a[i],len--;
}
}
return ;
}
bzoj 1046 LIS的更多相关文章
- BZOJ 1046 最长不降子序列(nlogn)
nlogn的做法就是记录了在这之前每个长度的序列的最后一项的位置,这个位置是该长度下最后一个数最小的位置.显然能够达到最优. BZOJ 1046中里要按照字典序输出序列,按照坐标的字典序,那么我萌可以 ...
- [BZOJ 1046] [HAOI2007] 上升序列 【DP】
题目链接:BZOJ - 1046 题目分析 先倒着做最长下降子序列,求出 f[i],即以 i 为起点向后的最长上升子序列长度. 注意题目要求的是 xi 的字典序最小,不是数值! 如果输入的 l 大于最 ...
- BZOJ 1046: [HAOI2007]上升序列 LIS -dp
1046: [HAOI2007]上升序列 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 3438 Solved: 1171[Submit][Stat ...
- BZOJ 1046: [HAOI2007]上升序列(LIS)
题目挺坑的..但是不难.先反向做一次最长下降子序列.然后得到了d(i),以i为起点的最长上升子序列,接下来贪心,得到字典序最小. ----------------------------------- ...
- BZOJ 1046 上升序列(LIS变形)
要保证长度为L的序列下标字典序最小,当然要尽量选前面的数. 如何判断前面的数是否满足条件?,只需要知道这个数开头的递增序列的最长长度是多少,如果不小于L,那么必然可以加入这个数.还需判断一下它是否大于 ...
- BZOJ 1046 [HAOI2007]上升序列(LIS + 贪心)
题意: m次询问,问下标最小字典序的长度为x的LIS是什么 n<=10000, m<=1000 思路: 先nlogn求出f[i]为以a[i]开头的LIS长度 然后贪心即可,复杂度nm 我们 ...
- 【BZOJ 1046】 1046: [HAOI2007]上升序列
1046: [HAOI2007]上升序列 Description 对于一个给定的S={a1,a2,a3,-,an},若有P={ax1,ax2,ax3,-,axm},满足(x1 < x2 < ...
- Bzoj 1046: [HAOI2007]上升序列 二分,递推
1046: [HAOI2007]上升序列 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 3671 Solved: 1255[Submit][Stat ...
- bzoj 1046 : [HAOI2007]上升序列 dp
题目链接 1046: [HAOI2007]上升序列 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 3620 Solved: 1236[Submit] ...
随机推荐
- VS05错误:部署WEB文件失败
直接生成一个空项目就不存在这个问题了.
- Keil MDK中Image~~RW_IRAM1~~ZI~~Limit(~表示$)
ARM程序的组成 此处所说的“ARM程序”是指在ARM系统中正在执行的程序,而非保存在ROM中的bin映像(image)文件,这一点清注意区别. 一个ARM程序包含3部分:RO, ...
- 【bzoj1616】[Usaco2008 Mar]Cow Travelling游荡的奶牛 bfs
题目描述 奶牛们在被划分成N行M列(2 <= N <= 100; 2 <= M <= 100)的草地上游走,试图找到整块草地中最美味的牧草.Farmer John在某个时刻看见 ...
- Python面向对象—类的继承
一个子类可以继承父类的所有属性,不管是父类的数据属性还是方法. class Father(object): num = 0 def __init__(self): print "I'm Pa ...
- [JSOI2009]计数问题 二维树状数组
---题面--- 题解: 二维树状数组的板子题,,,学了这么久第一次写二维树状数组,惭愧啊. 怎么写就不说了,看代码吧. 跟普通的是一样的写法 #include<bits/stdc++.h> ...
- Linux系统上的popen()库函数
popen可以是系统命令,也可以是自己写的程序a.out. 假如a.out就是打印 “hello world“ 在代码中,想获取什么,都可以通过popen获取. 比如获取ls的信息, 比如获取自己写的 ...
- ACE线程管理机制-线程的创建与管理
转载于:http://www.cnblogs.com/TianFang/archive/2006/12/04/581369.html 有过在不同的操作系统下用c++进行过多线程编程的朋友对那些线程处理 ...
- 蓝桥杯 最短路 spfa
问题描述 给定一个n个顶点,m条边的有向图(其中某些边权可能为负,但保证没有负环).请你计算从1号点到其他点的最短路(顶点从1到n编号). 输入格式 第一行两个整数n, m. 接下来的m行,每行有三个 ...
- DOM动态增加控件
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <t ...
- HDU1394 逆序数
Minimum Inversion Number Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java ...