zoukankan      html  css  js  c++  java
  • 最长严格递增子序列算法

    代码来源于:http://hi.baidu.com/daoyuanlee/blog/item/f5ccff07e58f69cf7a89473b.html

    O(n^2) 算法的思想

    基于动态规划:用数组a记录数字序列,数组b记录各a各个前缀子序列最长严格递增子序列的长度(即b[i]记录的是a[0]...a[i]的最长严格递增子序列的长度)

    显然有b[0]=1,即a[0]的最长严格递增子序列长度显然为1

    在这个情况下进行增长,a[1]如果比a[0]大,那么b[1]就为b[0]+1=2. 否则b[1]仍然为1(即最长严格递增子序列为a[0]或a[1])

    继续增长至a[0],a[1],...a[i-1]的情况,此时b中下标0至i的部分也存储了长度由1至i-2的a的前缀子序列最长严格递增子序列的长度。

    此时我们从0至i-1迭代,并维护一个max变量:

    1 int max = 0;
    2  for (j = 0; j < i; j ++)
    3 if (max < b[j] && a[j] < a[i]) max = b[j];
    4 b[i] = max + 1;

    迭代过程中维护一变量max,迭代中,当满足以下2条件时更新max:

    1. max < b[j]

    2. a[j] < a[i]

    使得max取到的是b[0]...b[i-1]中的最大值(假设为b[x]),即a[0]...a[i-1]的最长严格递增子序列的长度;且有a[x]<a[i],即下一个增长到尾部的元素可以为增加当前最长严格递增子序列的长度。

    因此a[0]...a[i]的最长严格递增子序列的长度为max+1.

    增长持续至整个序列都被加入后,只需要遍历b,取出其中最大的值,即为a的最长严格递增子序列的长度。

    O(n*logn)算法

    #include <iostream>

    using namespace std;

    const int MAX = 100;
    int b[MAX];

    int bs(int x,int k)
    {
    if(x < b[1]) return 1;
    int left = 1, right = k, mid;
    while(left < right-1)
    {
    mid
    = (left+right)/2;
    if(b[mid] <= x) left = mid;
    else right = mid;
    }
    return right;
    }

    int LIS(int n, int a[])
    {
    int k = 1;
    b[
    1] = a[0];
    for(int i = 1; i < n; ++i)
    {
    if(a[i] > b[k]) b[++k] = a[i];
    else if(a[i] != b[k]) b[bs(a[i], k)] = a[i];
    }
    return k;
    }

    int main()
    {
    int n, i, a[MAX];
    while(scanf("%d", &n) == 1)
    {
    for(i = 0; i < n; ++i) scanf("%d", &a[i]);
    printf(
    "%d\n", LIS(n, a));
    }
    return 0;
    }

  • 相关阅读:
    达梦数据库学习(二、管理数据库实例)
    达梦数据库学习(一、linux操作系统安装及数据库安装)
    SQL Server 数据库还原进度查看
    关于索引的学习(主要是聚集索引与非聚集索引)
    SQL Server批量向表中插入多行数据语句
    最大流-前置push-relabel算法实现
    调度算法(二)
    调度算法(一)
    软件工程:提问回顾
    软件工程:个人阅读作业与总结
  • 原文地址:https://www.cnblogs.com/mdyang/p/2031282.html
Copyright © 2011-2022 走看看