[THOJ 2471] lis 最值字典序

题意

  给定一个长度为 n 的序列 A .

  问是否存在一个长度为 L 的上升子序列.

  如果存在, 输出字典序最小的.

  N <= 100000 .

分析

  先按照 (key, pos) , 把上升子序列进行一些小小的转换, 变成选取坐标尽可能小的.

  处理出以每个位置开头的上升子序列的长度.

  然后贪心选取.

小结

  对于最值字典序的问题, 我们通常有这样一些处理手段:

    ① 通过排序等方法, 将问题进行转化.

    ② 每次尽可能选最后, 能得到最大字典序. (反过来做, 能得到最小字典序)

    ③ 预处理每个位置开头的上升子序列的长度, 然后用某些数据结构来选取.

实现

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cstdlib>
 4 #include <cctype>
 5 #include <algorithm>
 6 using namespace std;
 7 #define F(i, a, b) for (register int i = (a); i <= (b); i++)
 8 #define D(i, a, b) for (register int i = (a); i >= (b); i--)
 9 inline int rd(void) {
10     int f = 1; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == ‘-‘) f = -1;
11     int x = 0; for (; isdigit(c); c = getchar()) x = x*10+c-‘0‘; return x*f;
12 }
13
14 const int N = 100005;
15
16 int n, L;
17 struct Data {
18     int key, pos;
19     friend inline bool operator < (Data A, Data B) { return A.key != B.key ? A.key < B.key : A.pos < B.pos; }
20 }w[N];
21 int f[N], tr[N];
22
23 inline int lowbit(int i) { return i & -i; }
24 inline void Add(int x, int w) { for (int i = x; i <= n; i += lowbit(i)) tr[i] = max(tr[i], w); }
25 inline int Query(int x) { int Max = 0; for (int i = x; i > 0; i -= lowbit(i)) Max = max(Max, tr[i]); return Max; }
26
27 int main(void) {
28     #ifndef ONLINE_JUDGE
29         freopen("lis.in", "r", stdin);
30     #endif
31
32     n = rd(), L = rd();
33     F(i, 1, n) w[i] = (Data){rd(), i};
34     sort(w+1, w+n+1);
35
36     D(i, n, 1) {
37         f[i] = Query(n - w[i].pos + 1) + 1;
38         Add(n - w[i].pos + 1, f[i]);
39     }
40
41     if (*max_element(f+1, f+n+1) < L) puts("impossible"), 0;
42     for (int Last = -1, W = -1, i = 1; i <= n && L >= 1; i++)
43         if (f[i] >= L && Last < w[i].pos && W < w[i].key)
44             printf("%d ", w[i].key), L--, Last = w[i].pos, W = w[i].key;
45     puts("");
46
47     return 0;
48 }
时间: 2024-08-29 09:04:20

[THOJ 2471] lis 最值字典序的相关文章

HDU 5141 LIS again

Problem Description A numeric sequence of ai is ordered if a1<a2<-<aN. Let the subsequence of the given numeric sequence (a1,a2,-,aN) be any sequence (ai1,ai2,-,aiK), where 1≤i1<i2<-<iK≤N. For example, sequence (1, 7, 3, 5, 9, 4, 8) has

hoj_10027_优化DP(LIS)

Longest Ordered Subsequence Extention Time Limit: 1000ms, Special Time Limit:2500ms, Memory Limit:65536KB Total submit users: 778, Accepted users: 555 Problem 10027 : No special judgement Problem description A numeric sequence of ai is ordered if a1

简单动态数组的实现代码

以下是本人动态数组实现的源代码,仅供参考,不足之处请指正: import java.util.*; public class My_List implements Collection{ /***************************************************************/ //测试模块 //主方法,测试用 public static void main(String [] args){ /* My_List ma = new My_List(); /

AngularJS--不能回避的4个问题

AngularJS是一个很容易让人上瘾且深陷其中的JS框架,它的MVC特性大大减少的Web开发难度,提高代码后期的维护性.学会了这个框架,有时候甚至开发个最简单的静态页,你也会情不自禁问问自己,可以用Angular吗? 但事物都是有双面性的,简单说说那些AngularJS开发的. 一.体积庞大 AngularJS,核心模块加上route.cookies两个核心模块,压缩后min版本的体积大约120k,如果算上HTTP GZIP传输压缩的话,体积能缩减到60~70k左右那AngularJS的JS库

hdu_1025

LIS,只求长度,不求串的具体内容 // hdu 1025 // dp LIS binary_search // Feb.16 2015 #include <cstdio> #define MAXN 500000 int dp[MAXN + 10], n, road[MAXN + 10], case_num = 0, len; // dp[i] 代表长度为i的LIS的末尾数字 // int locate_time = 0; int binary_search(int num) { // 找到一

8.13联考题解

最长上升子串 时间限制: 2 Sec  内存限制: 64 MB 样例输入 67 2 3 1 5 6 样例输出 5 题解       刚一读题觉得和昨天T3相似度极高,只不过是久违的子串.还是想动归思路,f[i][1/0]表示到第i位是/否已经改变过序列的值,然后大概就是个择优转移的思路:受到昨天那题局限用一个辅助数组记录了一下改变后的值,贪心策略把它设为a[i-1][0]+1,.开始上手打,代码倒是很短,怎么想怎么觉得不对劲,自己凭着感觉开始刻意造数据卡这个做法.试了几组数之后成功用123745

【BZOJ 1046】 [HAOI2007]上升序列

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

UVa 1599 理想路径(反向BFS 求最短路径 )

题意: 给定一个有重边有自环的无向图,n个点(2 <= n <= 100000), m条边(1 <= m <= 200000), 每条边有一个权值, 求从第一个点到n的最少步数, 如果最少步数相同有多条路径, 那么输出权值字典序最小的一条. 分析: 用BFS解决最短路问题, 可以先从终点BFS, 求出每个点到终点的最短距离. 那么最少步数就是起点的最短距离, 最短路径就是从起点每次向最短距离比自己少1的顶点移动(如果有多个则可以随便走), 这样就可以保证走的是最短路径, 如果一开始

数据类型之一 列表

Pyhton  列表 首先需要进行声明,有两种方式: 1/ lis = []  2/ lis = list(); 列表的结构与PHP的数组类似,都可以内部进行嵌套 lis = ['a','b',['c','d']] 在python 中有回去列表索引值的方法   lis.index('a') 从左到右开始的第一个元素的位置 lis.count('a') 是获取该元素在列表中的个数 查询列表中的元素的方法 可以通过键值 键值可正可负  正表示从左开始算, 负表示从右开始算 其中 切片概念在查询列表时