最长上升子序列nlogn解法详解 poj 2533

先上一个n^2的算法:

 1 #include <iostream>
 2 using namespace std;
 3
 4 const int N = 1000;
 5 int a[N];
 6 int g[N];
 7
 8 int main ()
 9 {
10     int n;
11     while ( cin >> n )
12     {
13         for ( int i = 0; i < n; i++ )
14         {
15             cin >> a[i];
16             g[i] = 1;
17         }
18         int ans = g[0];
19         for ( int i = 1; i < n; i++ )
20         {
21             for ( int j = 0; j < i; j++ )
22             {
23                 if ( a[j] >= a[i] ) continue;
24                 if ( g[j] + 1 > g[i] ) g[i] = g[j] + 1;
25             }
26             if ( g[i] > ans ) ans = g[i];
27         }
28         cout << ans << endl;
29     }
30     return 0;
31 }

然后是nlogn的:

 1 #include <algorithm>
 2 #include <iostream>
 3 using namespace std;
 4
 5 const int INF = 1 << 29;
 6 const int N = 1000;
 7 int s[N];
 8 int top;
 9
10 int main ()
11 {
12     int n;
13     while ( cin >> n )
14     {
15         top = 0;
16         s[top++] = INF;
17         for ( int i = 0; i < n; i++ )
18         {
19             int tmp;
20             cin >> tmp;
21             if ( tmp > s[top - 1] )
22             {
23                 s[top++] = tmp;
24             }
25             else
26             {
27                 int pos = upper_bound( s, s + top, tmp ) - s;
28                 s[pos] = tmp;
29             }
30         }
31         cout << top << endl;
32     }
33     return 0;
34 }
时间: 2024-11-06 12:03:38

最长上升子序列nlogn解法详解 poj 2533的相关文章

最长不下降子序列nlogn算法详解

今天花了很长时间终于弄懂了这个算法……毕竟找一个好的讲解真的太难了,所以励志我要自己写一个好的讲解QAQ 这篇文章是在懂了这个问题n^2解决方案的基础上学习. 解决的问题:给定一个序列,求最长不下降子序列的长度(nlogn的算法没法求出具体的序列是什么) 定义:a[1..n]为原始序列,d[k]表示长度为k的不下降子序列末尾元素的最小值,len表示当前已知的最长子序列的长度. 初始化:d[1]=a[1]; len=1; (0个元素的时候特判一下) 现在我们已知最长的不下降子序列长度为1,末尾元素

DP练习 最长上升子序列nlogn解法

openjudge 百练 2757:最长上升子序列 总时间限制:  2000ms 内存限制:  65536kB 描述 一个数的序列bi,当b1 < b2 < ... < bS的时候,我们称这个序列是上升的.对于给定的一个序列(a1, a2, ..., aN),我们可以得到一些上升的子序列(ai1, ai2, ..., aiK),这里1 <= i1 < i2 < ... < iK <= N.比如,对于序列(1, 7, 3, 5, 9, 4, 8),有它的一些上

POJ 1631(最长上升子序列 nlogn).

~~~~ 由题意可知,因为左边是按1~n的顺序递增排列,要想得到不相交组合,左边后面的一定与相应右边后面的相连,如此一来, 就可以发现其实是一道最长上升子序列的题目,要注意的是N<40000,用n^2的算法一定会超时. 题目链接:http://poj.org/problem?id=1631 ~~~~ nlogn的算法在这里补充一下. 最长不下降子序列的O(nlogn)算法分析如下: 设 A[t]表示序列中的第t个数,F[t]表示从1到t这一段中以t结尾的最长上升子序列的长度,初始时设F [t]

最长上升子序列 nlogn

最长上升子序列中对于数ipt[i],向前遍历,当数ipt[j]小于ipt[i] 则ipt[j]可作为上升序列中ipt[i]的前一个数字 dp[i] = max{ dp[j] + 1 | j < i && ipt[j] < ipt[i]} 若现在有两个状态a,b 满足dp[a] = dp[b]且 ipt[a] < ipt[b]  则对于后面的状态dp[a]更优  因为若ipt[i] > dp[b] 则必然ipt[i] > dp[a],反之若ipt[i] >

hdu 1025 Constructing Roads In JGShining&#39;s Kingdom(最长上升子序列nlogn算法)

学习了最长上升子序列,刚开始学的n^2的方法,然后就超时了,肯定超的,最大值都是500000,平方之后都12位 了,所以又开始学nlogn算法,找到了学长党姐的博客orz,看到了rating是浮云...确实啊,这些不必太关 注,作为一个动力就可以啦.没必要看的太重,重要的事学习知识. 思路: 这道题目可以先对一行排序,然后对另一行求最长上升子序列... n^2算法: 序列a[n],设一个数组d[n]表示到n位的时候最长公共子序列(此序列包括n),所以呢 d[n]=max(d[j]+1,0<j<

最长上升子序列O(nlogn)算法详解

最长上升子序列 时间限制: 10 Sec   内存限制:128 MB 题目描述 给定一个序列,初始为空.现在我们将1到N的数字插入到序列中,每次将一个数字插入到一个特定的位置.我们想知道此时最长上升子序列长度是多少? 输入 第一行一个整数N,表示我们要将1到N插入序列中,接下是N个数字,第k个数字Xk,表示我们将k插入到位置Xk(0<=Xk<=k-1,1<=k<=N) 输出 1行,表示最长上升子序列的长度是多少. 样例输入 3 0 0 2 样例输出 2 提示 100%的数据 n&l

最长上升子序列LIS解法(n^n &amp;&amp; nlogn)

最长递增子序列问题 在一列数中寻找一些数满足 任意两个数a[i]和a[j] 若i<j 必有a[i]<a[j] 这样最长的子序列称为最长递增子序列LIS LIS问题有两种常见的解法 一种时间复杂度n^n 一种时间复杂度nlogn 下面我们先来说一下n^n的算法 设dp[i]表示以i结尾的最长上升子序列的长度 把问题分解 分解成序列中每一项最为终点的最大上升子序列 从第二项开始依次判断 最后找出最大的一项就是答案 则状态转移方程为 dp[i] = max{dp[j]+1}, 1<=j<

最长公共子序列 nlogn

先来个板子 #include<bits/stdc++.h> using namespace std; const int N = 1e6+20, M = 1e6+10, mod = 1e9+7, inf = 1e9+1000; typedef long long ll; struct node { int c; int num; } u[N]; int i,j,k = 0,n,m,x,y = 0,T = 0,ans = 0,big = 0,cas = 0,num = 0,len = 0; bo

LIS最长上升子序列 (nlogn) poj1631

问题描述:LIS(Longest Increasing Subsequence)最长上升(不下降)子序列,有两种算法复杂度为O(n*logn)和O(n^2).在上述算法中,若使用朴素的顺序查找在D1..Dlen查找,由于共有O(n)个元素需要计算,每次计算时的复杂度是O(n),则整个算法的时间复杂度为O(n^2),与原来算法相比没有任何进步.但是由于D的特点(2),在D中查找时,可以使用二分查找高效地完成,则整个算法时间复杂度下降为O(nlogn),有了非常显著的提高.需要注意的是,D在算法结束