LIS的nlogn

nlogn老忘,开个帖记录一下

开一个栈,每次取栈顶元素top和读到的元素temp做比较,如果temp > top 则将temp入栈;如果temp < top则二分查找栈中的比temp大的第1个数,并用temp替换它。 最长序列长度即为栈的大小top。

例如对2 1 5 3 6 4 8 9 7

每一步的结果

1.  2

2.  1

3.  1 5

4.  1 3

5.  1 3 6

6.  1 3 4

7.  1 3 4 8

8.  1 3 4 8 9

9.  1 3 4 7 9

最后的13479并不是LIS,而是对应LIS长度的最小末尾,记录栈顶元素即可求出对应LIS序列

const int MAXN=500010;
int a[MAXN],b[MAXN];
//用二分查找的方法找到一个位置,使得num>b[i-1] 并且num<b[i],并用num代替b[i]
int Search(int num,int low,int high)
{
    int mid;
    while(low<=high)
    {
        mid=(low+high)/2;
        if(num>=b[mid]) low=mid+1;
        else high=mid-1;
    }
    return low;
}
int DP(int n)
{
    int i,len,pos;
    b[1]=a[1];
    len=1;
    for(i=2;i<=n;i++)
    {
        if(a[i]>=b[len])//如果a[i]比b[]数组中最大还大直接插入到后面即可
        {
            len=len+1;
            b[len]=a[i];
        }
        else//用二分的方法在b[]数组中找出第一个比a[i]大的位置并且让a[i]替代这个位置
        {
            pos=Search(a[i],1,len);
            b[pos]=a[i];
        }
    }
    return len;
}
时间: 2024-11-10 09:21:47

LIS的nlogn的相关文章

HDU ACM 1025 Constructing Roads In JGShining&amp;#39;s Kingdom-&amp;gt;二分求解LIS+O(NlogN)

#include<iostream> using namespace std; //BFS+优先队列(打印路径) #define N 500005 int c[N]; int dp[N]; //dp[i]保存的是长度为i的最长不降子序列的最小尾元素 int BS(int n,int x) //二分查找下标,当x比全部元素小时下标为1,比全部元素大时下标为n+1. { int low,high,mid; low=1,high=n; while(low<=high) { mid=(low+h

NOIp模拟1 Incr(LIS的nlogn算法)

[分析] 这题就是拿总长度减去LIS啦,很明显. 问题是数据范围,这里用n^2就会超时,所以我们选用LIS的nlogn算法,如下. [代码] 1 #include <bits/stdc++.h> 2 #define inf 0x7fffffff 3 using namespace std; 4 5 int n, a[100005], k, f[100005], ans; 6 int g[100005];//记录当前的最优子序列 7 8 int main() { 9 cin >> n

HDU ACM 1025 Constructing Roads In JGShining&#39;s Kingdom-&gt;二分求解LIS+O(NlogN)

#include<iostream> using namespace std; //BFS+优先队列(打印路径) #define N 500005 int c[N]; int dp[N]; //dp[i]保存的是长度为i的最长不降子序列的最小尾元素 int BS(int n,int x) //二分查找下标,当x比所有元素小时下标为1,比所有元素大时下标为n+1. { int low,high,mid; low=1,high=n; while(low<=high) { mid=(low+h

ACdream 1216——Beautiful People——————【二维LIS,nlogn处理】

Beautiful People Special Judge Time Limit: 2000/1000MS (Java/Others) Memory Limit: 128000/64000KB (Java/Others) Submit Statistic Next Problem Problem Description The most prestigious sports club in one city has exactly N members. Each of its members

LIS 的 nlogn算法

HOJ 1288 Bridging Signals http://acm.hit.edu.cn/hoj/problem/view?id=1288 以前只知道也只听说过 O(n*n) 的LIS 算法 但是过不了这个题,结果才知道还有一种O(nlogn)的算法. 具体思路就是用一个数组ans[len] 记录下对应 len 长度的 LIS 的最末尾元素的最小值. 这样的到的ans[len] 是一个有序的数组,所以用二分查找就能优化时间复杂度. 设 a[n] = 3,5,1,2,4; =========

BZOJ 1609 [Usaco2008 Feb]Eating Together麻烦的聚餐:LIS &amp; LDS (nlogn)

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1609 题意: 给你一个只由数字"1,2,3"组成的序列a[i],共n个数. 你可以任意更改这些数字,使得序列中每一种数字都"站在一起",并且单调不减或不增. 例如:"1111222", "332211"... 问你至少更改多少个数字. 题解: 单调不减:求原序列LIS(最长非降子序列),当前答案t1 = n - LIS

LeetCode Longest Increasing Subsequence (LIS O(nlogn))

题意: 给一个数组,求严格递增的最长递增子序列的长度. 思路: 开销是一个额外的O(n)的数组.lower_bound(begin,end,val)的功能是:返回第一个大于等于val的地址. 1 class Solution { 2 public: 3 int lengthOfLIS(vector<int>& nums) { 4 if(nums.empty()) return 0; 5 int *p=new int[nums.size()]; 6 p[0]=nums[0]; 7 int

tyvj 1067 dp 两次LIS(nlogn)

P1067 合唱队形 时间: 1000ms / 空间: 131072KiB / Java类名: Main 背景 NOIP2004 提高组 第三道 描述 N位同学站成一排,音乐老师要请其中的(N-K)位同学出列,使得剩下的K位同学排成合唱队形. 合唱队形是指这样的一种队形:设K位同学从左到右依次编号为1,2…,K,他们的身高分别为T1,T2,…,TK,  则他们的身高满足T1<...<Ti>Ti+1>…>TK(1<=i<=K). 你的任务是,已知所有N位同学的身高,

HDU 1950 Bridging signals(LIS O(nlogn))

Bridging signals Problem Description 'Oh no, they've done it again', cries the chief designer at the Waferland chip factory. Once more the routing designers have screwed up completely, making the signals on the chip connecting the ports of two functi