POJ 2533 O(nlogn)解最长递增子序列(构造法)

原创 2015年11月19日 19:22:16

Longest Ordered Subsequence
Time Limit: 2000MS Memory Limit: 65536K
Total Submissions: 41083 Accepted: 18109
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 ordered subsequences, e. g., (1, 7), (3, 4, 8) and many others. All longest ordered subsequences are of length 4, e. g., (1, 3, 5, 8).

Your program, when given the numeric sequence, must find the length of its longest ordered subsequence.
Input

The first line of input file contains the length of sequence N. The second line contains the elements of sequence - N integers in the range from 0 to 10000 each, separated by spaces. 1 <= N <= 1000
Output

Output file must contain a single integer - the length of the longest ordered subsequence of the given sequence.
Sample Input

7
1 7 3 5 9 4 8
Sample Output

4

题意:
求一个序列的最长递增子序列,输出这个子序列的长度。
解法:
这是一个经典的dp问题,转移方程是dp[i] = dp[j] + 1,0 < j < i-1,并且j是在a[j] < a[i]范围内dp[j]最大的。由于每次寻找时,我们知道在a[j] < a[i]的范围内dp[j]是最大的。因此要顺序便利,这样总时间复杂度就是O(n^2)
给人的感觉就是在搜索j时顺序遍历太不聪明了。这一步应该有更好的办法。由此有二个算法。
考虑构造一个数组b[],这个数组里放的是已经找到的最优递增序列,那么,我们开始遍历a[i],如果a[i]比数组b[]最大一个元素(即最后一个元素)还要大。那么就把a[i]添加到数组b[]的尾部。如果不比最后一个元素大,那就在b[]里查找第一个比a[i]大的元素,然后将那个元素替换为a[i].保证b[]里面的元素是递增排列的。并且当a[i]可以替代b[]里的元素时进行替代。由于b[]里元素是有序的。因此可以用二分查找,就达到了优化的目标。时间复杂度变为O(nlogn).
在poj上此题用上O(nlogn)的算法,时间降从原来dp算法的16ms到0ms

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>

using namespace std;

int a[10010];
int b[10010];

int main()
{
    int n;
    scanf("%d",&n);
    int i,j;
    for(i = 1;i<=n;i++)
        scanf("%d",&a[i]);
    b[1] = a[1];
    int cnt = 1;
    for(i = 2;i<=n;i++){
        if(a[i]>b[cnt]) b[++cnt] = a[i];
        else{
            int k = lower_bound(b+1,b+cnt+1,a[i]) - b;
            b[k] = a[i];
        }
    }
    printf("%d",cnt);
    return 0;
}

poj 2533(最长上升子序列)(n^2 ) 和 nlogn的算法

题目链接:点击打开链接 题目大意:略 题目分析:1.用n平方的做法,枚举以data【i】为结尾的子序列,向前查找,比data【i】小并且dp【j】比dp【i】小的 新手代码: #include #i...
  • u011613321
  • u011613321
  • 2013年08月26日 15:27
  • 751

POJ2533 DP入门级题目-最大上升子序列(LIS)-O(n^2)与O(nlogn) (变形,POJ1631)

1) #include //入门DP问题,时间复杂度O(N^2) using namespace std; int main() { int a[1010];//输入元素 int d...
  • a272846945
  • a272846945
  • 2016年02月26日 21:34
  • 762

最长递增子序列O(NlogN)算法(leetcode 300. Longest Increasing Subsequence )

最长递增子序列,Longest Increasing Subsequence 下面我们简记为 LIS。 排序+LCS算法 以及 DP算法就忽略了,这两个太容易理解了。 假设存在一个序列d[1....
  • jiary5201314
  • jiary5201314
  • 2016年04月16日 21:06
  • 2294

POJ 2533最长递增子序列O(nlogn) 算法

这个算法其实已经不是DP了,有点像贪心。至于复杂度降低其实是因为这个算法里面用到了二分搜索。本来有N个数要处理是O(n),每次计算要查找N次还是O(n),一共就是O(n^2);现在搜索换成了O(log...
  • caizi1991
  • caizi1991
  • 2014年04月04日 16:16
  • 425

最长公共子序列及最长递增子序列NlogN算法及路径记录

原文链接 最长公共子序列路径记录 最长公共子序列转化为最长递增子序列问题,O( n*log(n) )   (转自:http://karsbin.blog.51cto.com/1156716/96...
  • qq_32680617
  • qq_32680617
  • 2016年10月15日 13:40
  • 488

单调递增最长子序列 O(nlogn)

单调递增最长子序列 时间限制:3000 ms  |  内存限制:65535 KB 难度:4 描述求一个字符串的最长递增子序列的长度 如:dabdbf最长递增子序列就是abdf,长度为4 ...
  • u011455899
  • u011455899
  • 2014年02月15日 12:24
  • 721

最长递增子序列(LIS)的O(NlogN)打印算法

题目: 求一个一维数组arr[n]中的最长递增子序列的长度,如在序列1,5,8,3,6,7中,最长递增子序列长度为4 (即1,3,6,7)。 方法一:一般的DP方法(O(N^2)) 像LC...
  • synapse7
  • synapse7
  • 2013年09月17日 09:39
  • 4497

最长递增子序列 O nlgn时间复杂度

[编程题]最长递增子序列 对于一个数字序列,请设计一个复杂度为O(nlogn)的算法,返回该序列的最长上升子序列的长度,这里的子序列定义为这样一个序列U1,U2...,其中Ui ...
  • u012605629
  • u012605629
  • 2015年08月28日 15:17
  • 889

最长递增子序列 LIS 时间复杂度O(nlogn)的Java实现

求最长递增(递减)子序列 LIS时间复杂度O(nlogn)的Java实现...
  • iNiegang
  • iNiegang
  • 2015年08月15日 13:20
  • 2258

最长递增子序列 O(NlogN)算法

最长递增子序列 O(NlogN)算法
  • dongmianshu
  • dongmianshu
  • 2010年10月20日 20:16
  • 3745
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:POJ 2533 O(nlogn)解最长递增子序列(构造法)
举报原因:
原因补充:

(最多只允许输入30个字)