sicily LIS

http://soj.sysu.edu.cn/show_problem.php?pid=1000&cid=1762

这题的n达到了1000000,n^2的最长递增子序列做法肯定超时,于是有一种二分的算法,与此题完美地结合起来!达到nlogn的时间复杂度!

 1 /*
 2 最长递增子序列+二分查找
 3 因为在获得最长递增子序列的时候,dp数组是有序的,所以把数加进去的时候,就合理地可以用二分啦!
 4
 5 a:  1 7 3 5 9 4 8
 6 dp: 0 0 0 0 0 0 0 0
 7
 8 a:  1 7 3 5 9 4 8
 9 dp: 0 1 0 0 0 0 0 0 (初始化:dp[1] = a[0],下标从1开始,代表最长递增子序列的长度)
10
11 a:  1 7 3 5 9 4 8
12 dp: 0 1 7 0 0 0 0 0 (7找不到比他小的,补在后面)
13
14 a:  1 7 3 5 9 4 8
15 dp: 0 1 3 0 0 0 0 0 (3找到7且小于它,替换之)
16
17 ......到最后......
18
19 a:  1 7 3 5 9 4 8
20 dp: 0 1 3 4 8 0 0 0 (此时长度为4,最后刚好是8)
21
22 */
23
24 #include <iostream>
25 #include <cstring>
26 #include <cstdio>
27
28 using namespace std;
29
30 int a[1000005];
31 int dp[1000005];
32
33 int binary_search(int l, int r, int key)
34 {
35     if(dp[r] <= key)
36         return r+1;
37     while(l < r) //不能等于啊
38     {
39         int mid = (l + r) / 2;
40         if(dp[mid] <= key)
41             l = mid + 1;
42         else
43             r = mid;
44     }
45     return l;
46 }
47
48 int LIS(int n)
49 {
50     memset(dp, 0, sizeof(dp));
51     int len = 1;
52     dp[1] = a[0];
53     for(int i=1; i<n; i++)
54     {
55         int pos = binary_search(1, len, a[i]);
56         dp[pos] = a[i];
57         if(len < pos)
58             len = pos;
59     }
60     return len;
61 }
62
63 int main()
64 {
65     int n;
66     while(scanf("%d", &n) != EOF)
67     {
68         for(int i=0; i<n; i++)
69             scanf("%d", &a[i]);
70         int len = LIS(n);
71         printf("%d ", len);
72         printf("%d\n", dp[len]);
73     }
74     return 0;
75 }
时间: 2024-10-10 13:01:50

sicily LIS的相关文章

小明系列问题――小明序列(LIS)

小明系列问题――小明序列 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Practice HDU 4521 Description 大家都知道小明最喜欢研究跟序列有关的问题了,可是也就因为这样,小明几乎已经玩遍各种序列问题了.可怜的小明苦苦地在各大网站上寻找着新的序列问题,可是找来找去都是自己早已研究过的序列.小明想既然找不到,那就自己来发明一个新的序列问题吧!

hdu4521 小明系列问题——小明序列(LIS变种 (线段树+单点更新解法))

链接: huangjing 题目:中文题目 思路: 这个题目如果去掉那个距离大于d的条件,那么必然是一个普通的LIS,但是加上那个条件后就变得复杂了.用dp的解法没有看懂,我用的线段树的解法...就是采用延迟更新的做法,用为距离要大于d啊,所以我们在循环到第i的时候,就对(i-d-1)这个点进行更新,因为如果在(i-d-1)这个点更新了,会对后面的造成影响,然后线段树的tree[]数组存的是以i结尾的最长lis,那么每次询问的时候就找最大的tree[]就可以了... 代码: 小明系列问题--小明

RQNOJ 201 奥运大包围:LIS + 拼链成环

题目链接:https://www.rqnoj.cn/problem/201 题意: 开始时n(n<=1000)个人手拉手围成一个圈. 后来这些人中的一些按顺序向里面出圈形成一个新圈.从而使原圈形成一个从高到低,最低与最高连接的圈. 新圈重复相同的操作,直到没有人要出圈为止. 问最少要形成多少个这样的圈. 题解: (1)拼链成环: 对于一个环,可以用两条由环拆开的链拼在一起表示. 例如:有一个环为"1,2,3,4"(1和4连在一起),则可以表示为"1,2,3,4,1,2,

Gym 101246H ``North-East&#39;&#39;(LIS)

http://codeforces.com/gym/101246/problem/H 题意: 给出n个点的坐标,现在有一个乐队,他可以从任一点出发,但是只能往右上方走(包括右方和上方),要经过尽量多的点.输出它可能经过的点和一定会经过的点. 思路: 分析一下第一个案例,在坐标图上画出来,可以发现,他最多可以经过4个点,有两种方法可以走. 观察一下,就可以发现这道题目就是要我们求一个LIS. 首先,对输入数据排一下顺序,x小的排前,相等时则将y大的优先排前面. 用二分法求LIS,这样在d数组中就可

[SDOI2014]LIS

题目描述 给定序列A,序列中的每一项Ai有删除代价Bi和附加属性Ci.请删除若干项,使得4的最长上升子序列长度减少至少1,且付出的代价之和最小,并输出方案. 如果有多种方案,请输出将删去项的附加属性排序之后,字典序最小的一种. 输入输出格式 输入格式: 输入包含多组数据. 输入的第一行包含整数T,表示数据组数.接下来4*T行描述每组数据. 每组数据的第一行包含一个整数N,表示A的项数,接下来三行,每行N个整数A1..An,B1.,Bn,C1..Cn,满足1 < =Ai,Bi,Ci < =10^

洛谷U4727小L的二叉树[树 LIS]

题目背景 勤奋又善于思考的小L接触了信息学竞赛,开始的学习十分顺利.但是,小L对数据结构的掌握实在十分渣渣. 所以,小L当时卡在了二叉树. 题目描述 在计算机科学中,二叉树是每个结点最多有两个子结点的有序树.通常子结点被称作“左孩子”和“右孩子”.二叉树被用作二叉搜索树和二叉堆.随后他又和他人讨论起了二叉搜索树.什么是二叉搜索树呢?二叉搜索树首先是一棵二叉树.设key[p]表示结点p上的数值.对于其中的每个结点p,若其存在左孩子lch,则key[p]>key[lch]:若其存在右孩子rch,则k

hdu 1087(LIS变形)

Super Jumping! Jumping! Jumping! Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 31458    Accepted Submission(s): 14128 Problem Description Nowadays, a kind of chess game called “Super Jumping!

poj 2533 Longest Ordered Subsequence(LIS)

Description A numeric sequence of ai is ordered ifa1 <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

hdu5125(LIS)

相当于用多个O(nlog(n))LIS来做. // // main.cpp // 160322 // // Created by 陈加寿 on 16/3/22. // Copyright © 2016年 chenhuan001. All rights reserved. // #include <iostream> #include <stdio.h> #include <math.h> #include <vector> #include <stri