zoukankan      html  css  js  c++  java
  • (LIS)最长上升序列(DP+二分优化)

    求一个数列的最长上升序列

      动态规划法:O(n^2)

     1 //DP
     2 int LIS(int a[], int n)
     3 {
     4     int DP[n];
     5     int Cnt=-1;
     6     memset(DP, 0, sizeof(DP));
     7     for(int i=0; i<n; i++ )
     8     {
     9         for(int j=0; j<i; j++ )
    10         {
    11             if( a[i]>a[j] )
    12             {
    13                 DP[i] = max(DP[i], DP[j]+1);
    14                 Cnt = max(DP[i], Cnt);//记录最长序列所含元素的个数
    15             }
    16         }
    17     }
    18     return Cnt+1;//因为初始化为0,所以返回结果+1
    19 }

    贪心+二分法:O(nlogn) 

    分析:要让一个序列具有最长上升子序列,其实就是保证子序列中的每个元素尽可能小,降低门槛,让后面的元素尽可能多进入该子序列

    实现:定义一个最长子序列数组Array,以及当前长度Len,从头到尾维护数组a

    a. a[i]>Array[i] (当前元素大于子序列结尾元素),则a[i]进入子序列:Array[++len] = a[i]

    b. a[i]<=Array[i],这时对Array进行维护,把Array中比a[i]大的第一个元素替换成a[i](这样可以降低后面元素进入子序列的门槛。

    c. 为了降低算法复杂度,因为Array是升序序列,所以用lower_bound查找Array中第一个大于等于a[i]的元素

     1 //贪心+二分
     2 int LIS(int a[])
     3 {
     4     int Cnt=0;
     5     int Array[n+1];
     6     Array[0] = a[0];
     7     for(int i=1; i<n; i++ )
     8     {
     9         if( a[i]>Array[Cnt] )
    10             Array[++Cnt]=a[i];
    11             else
    12             {
    13                 int Index=lower_bound(Array, Array+Cnt+1, a[i])-Array;
    14                 Array[Index]=a[i];
    15             }
    16     }
    17     return Cnt+1;
    18 }

    求最长下降子序列:

        不需要再写LDS---直接将要求的数组倒序,倒序数组的最长上升子序列长度=原数组最长下降子序列长度。

  • 相关阅读:
    RabbitMq+Haproxy负载均衡
    RabbitMq常用命令
    几种常见的消息队列
    RabbitMq集群搭建
    a=a+b与a+=b的区别
    Redis集群搭建
    变量作用域
    8.3吝啬SAT问题
    Surrounded Regions
    Binary Tree Maximum Path Sum
  • 原文地址:https://www.cnblogs.com/wsy107316/p/11502538.html
Copyright © 2011-2022 走看看