bzoj1046

反向做最长下降子序列+贪心就行了(不过这数据我觉得n2能a)

 1 #include<bits/stdc++.h>
 2 #define lowbit(a) ((a)&(-(a)))
 3 #define clr(a,x) memset(a,x,sizeof(a))
 4 #define rep(i,l,r) for(int i=l;i<(r);i++)
 5 #define down(i,r,l) for(int i=r;i>=(l);i--)
 6 typedef long long ll;
 7 using namespace std;
 8 int read()
 9 {
10     char c=getchar();
11     int ans=0,f=1;
12     while(!isdigit(c)){
13         if(c==‘-‘) f=-1;
14         c=getchar();
15     }
16     while(isdigit(c)){
17         ans=ans*10+c-‘0‘;
18         c=getchar();
19     }
20     return ans*f;
21 }
22 const int maxn=10009,maxm=1009,inf=0x7fffffff;
23 int n,m,a[maxn],g[maxn],d[maxn];
24 int lowerbound(int l,int r,int a){
25     if(l==r) return l;
26     int mid=(l+r)>>1;
27     return g[mid]<=a?lowerbound(l,mid,a):lowerbound(mid+1,r,a);
28 }
29 int main()
30 {
31     n=read();
32     rep(i,0,n) a[i]=read(),g[i+1]=-inf;
33     down(i,n-1,0){
34         int p=lowerbound(1,n,a[i]);
35         d[i]=p;
36         g[p]=a[i];
37     }
38     m=read();
39     while(m--){
40         int l=read();
41         if(g[l]==-inf) puts("Impossible");
42         else{
43             int last=-inf;
44             rep(i,0,n){
45                 if(d[i]>=l&&a[i]>last){
46                     printf("%d",a[i]);
47                     last=a[i];
48                     if(!--l) break;
49                     printf(" ");
50                 }
51             }
52             puts("");
53         }
54     }
55     return 0;
56 }

1046: [HAOI2007]上升序列

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 3084  Solved: 1040
[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

6
3 4 1 2 3 6
3
6
4
5

Sample Output

Impossible
1 2 3 6
Impossible

HINT

数据范围

N<=10000

M<=1000

Source

[Submit][Status][Discuss]

时间: 2024-10-10 07:24:25

bzoj1046的相关文章

[BZOJ1046][HAOI2007]上升序列 DP+贪心

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1046 我们先求出对于每一个数字作为开头的LCS的长度f[i],最长的f[i]为mxlen. 对于每一个询问,我们选取答案,从第1个开始选.假设当前已经选到了第x个答案,我们只需要一直往后面找到第一个f[k]且f[k]+x>mxlen,它就是第x+1个答案. 这样时间复杂度就是$O(nm)$的,感觉玄学卡过…… 1 #include<cstdio> 2 #include<cs

[bzoj1046][HAOI2007]上升序列

题意:对于一个给定的S={a1,a2,a3,-,an},若有P={ax1,ax2,ax3,-,axm},满足(x1 < x2 < - < xm)且( ax1 < ax2 < - < axm).那么就称P为S的一个上升序列. 有m个询问,每次询问一个长度L,如果没有长度为L的上升序列,输出Impossible,要不然求一个字典序最小的上升序列. (这题的字典序最小居然指的是下标) n<=10000,m<=1000 题解:倒着dp,用线段树求出每个点和它后面最长

【bzoj1046】[HAOI2007]上升序列

首先求出以每个数为开头上升序列长度,即倒着做最长下降子序列 然后,把字典序尽量小的放前面 即若要求的序列长度为x,如果以第一个数(字典序最小的数)开头的最长上升子序列大等于x,则将它放在答案第一个,第二个数开头小于x,则舍弃,第三个大于x-1,放答案第二个,以此类推 #include<algorithm> #include<iostream> #include<cstdlib> #include<cstring> #include<cstdio>

[BZOJ1046] [HAOI2007] 上升序列 (dp)

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的上升序列

BZOJ1046 上升序列

题解: 神TM的字典序最小......这题的字典序最小是位置的字典序最小...仔细读读题目 所以.我们求出以每个点为起点的最长递增子序列..然后输出的话.贪心就行 如何求每个点为起点的最长递增子序列 回忆一下LIS的o(nlog(n))算法 我们逆向求最长递减子序列即可. 代码: #include<bits/stdc++.h> using namespace std; #define pb push_back #define mp make_pair #define se second #de

【动态规划】【最长上升子序列】【贪心】bzoj1046 [HAOI2007]上升序列

nlogn求出最长上升子序列长度. 对每次询问,贪心地回答.设输入为x.当前数a[i]可能成为答案序列中的第k个,则若 f[i]>=x-k && a[i]>ans[k-1] 即可. f[i]表示以a[i]开头的最长上升子序列长度. 但这个东西难以统计.so 我们将原序列反序,求f[i] 表示以 a[i]为结尾的最长下降子序列长度即可.最后再将f.a reverse一下. 1 #include<cstdio> 2 #include<algorithm> 3

【BZOJ-1046】上升序列 DP + 贪心

1046: [HAOI2007]上升序列 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 3723  Solved: 1271[Submit][Status][Discuss] Description 对于一个给定的S={a1,a2,a3,…,an},若有P={ax1,ax2,ax3,…,axm},满足(x1 < x2 < … < xm)且( ax1 < ax2 < … < axm).那么就称P为S的一个上升序列.如果有多

noip知识点总结之--贪心

一.什么是贪心 贪心算法嘛... 就是在对某个问题求解时,总是做出在当前看来是最好的选择 In other wors,并不是从整体最优上加以考虑,而是在获得某种意义上的局部最优解 二.贪心算法的适用前提 局部的最优解能导致最后整体的最优解,即局部的最优解不受该部分以外的东西的影响 对于贪心算法,我们需要证明:整个问题的最优解一定由在贪心策略中存在的子问题的最优解得来的 实际上,能用贪心算法的问题很少,大部分看上去能用贪心算法去做的题目,其实都得不到最优解T T(这时候就需要运用动态规划了) 而看

大神刷题表

9月27日 后缀数组:[wikioi3160]最长公共子串 dp:NOIP2001统计单词个数 后缀自动机:[spoj1812]Longest Common Substring II [wikioi3160]最长公共子串 [spoj7258]Lexicographical Substring Search 扫描线+set:[poj2932]Coneology 扫描线+set+树上删边游戏:[FJOI2013]圆形游戏 结论:[bzoj3706][FJ2014集训]反色刷 最小环:[poj1734