zoukankan      html  css  js  c++  java
  • 最长上升子序列

    对于一个数列a1,a2,a3,a4……求取其最长的子序列s1,s2,s3……使其满足单调递增的算法,叫做最长上升子序列

    对于该问题有两种思路:

    • 动态规划方法求解 O(n2)
    • 贪心+二分 O(nlogn)

    动态规划

    A[i]表示序列中的第i个数

    dp[i]表示从1到i这一段中以i结尾的最长上升子序列的长度

    初始时设dp[i] = 0(i = 1, 2, ...)。

    则有动态规划方程:dp[i] = max{1, dp[j] + 1} (j = 1, 2, ..., i - 1, 且A[j] < A[i])

    贪心+二分

    构造一个有顺序的栈s

    每次取栈顶元素top和读取到的元素a

    if top<a

      s.push(a)

    else

      用a替换栈中第一个比a大的数

    最后栈中的元素的数量就是所求的数量(但是栈中元素可能并不是最长上升子序列)


    举例:原序列为1,5,8,3,6,7  
    栈为1,5,8,此时读到3,则用3替换5,得到栈中元素为1,3,8,  再读6,用6替换8,得到1,3,6,再读7,得到最终栈为1,3,6,7  ,最长递增子序列为长度4。 

    模板代码:GitHub

    class LIS_stack {
    private:
        static const int SIZE = maxn;//最大长度
        int len;//长度
        int Stack[SIZE];
    public:
        LIS_stack() {
            len = 0;
            memset(Stack,0,sizeof(Stack));
        }
        void push(int num) {
            if(len == 0 || Stack[len - 1] < num) {
                Stack[len++] = num;
            } else {
                for(int i = 0;i < len;i++) {
                    if(Stack[i] > num) {
                        Stack[i] = num;
                        break;
                    }
                }
            }
        }
        int lenth() {
            return len;
        }
    
    };
    
    int LIS(int *a,int len) {
        LIS_stack s;
        for(int i = 0;i < len;i++) 
            s.push(a[i]);
        return s.lenth();
    }
  • 相关阅读:
    经典面试题回答——学习Java基础的目的
    Woody的逻辑游戏--怎样换轮胎
    skype默认占用80和443port
    opencl+opencv实现sobel算法
    Rational 最新软件试用下载地址
    leetcode-20-Valid Parentheses
    JPA学习笔记(11)——使用二级缓存
    新浪微博授权登陆获取个人信息
    Ubuntu 12.04 64bit GCC交叉编译器制作 原创
    表单兼容类型设计
  • 原文地址:https://www.cnblogs.com/ohyee/p/5449629.html
Copyright © 2011-2022 走看看