zoukankan      html  css  js  c++  java
  • 51Nod 1134 最长递增子序列

    给出长度为N的数组,找出这个数组的最长递增子序列。(递增子序列是指,子序列的元素是递增的)
    例如:5 1 6 8 2 4 5 10,最长递增子序列是1 2 4 5 10。
     
    Input
    第1行:1个数N,N为序列的长度(2 <= N <= 50000)
    第2 - N + 1行:每行1个数,对应序列的元素(-10^9 <= S[i] <= 10^9)
    Output
    输出最长递增子序列的长度。
    Input示例
    8
    5
    1
    6
    8
    2
    4
    5
    10
    Output示例
    5

    思路:一开始没想那么多,直接dp,后面发现超时了,查了下最长上升子序列的解法发现有一种模拟栈操作的解法,时间复杂度为O(nlogn).套一下板子就行了,主要还是理解这份模板如何运行的
    自己用代码测了下,当输入的数>top是,加入栈中并设为top,当输入的数<top时,找到栈中第一个大于它的数字并替换掉,这样虽然长度没有变化,但他的”潜力“变大了。最后top就是子序列最大长度了
    算法主要还是贪心思想,用二分缩短时间。

    实现代码:
    #include <iostream>
    
    using namespace std;
    
    int main()
    {
        int i, j, n, top, temp;
        int stack[1001];
        while(cin >> n)
       {
        top = 0;
        stack[0] = -1199999999;
        for (i = 0; i < n; i++)
        {
            cin >> temp;
            /* 比栈顶元素大数就入栈 */
            if (temp > stack[top])
            {
                stack[++top] = temp;
            }
            else
            {
                int low = 1, high = top;
                int mid;
                /* 二分检索栈中比temp大的第一个数 */
                while(low <= high)
                {
                    mid = (low + high) / 2;
                    if (temp > stack[mid])
                    {
                        low = mid + 1;
                    }
                    else
                    {
                        high = mid - 1;
                    }
                }
                /* 用temp替换 */
                stack[low] = temp;
            }
        }
    
        /* 最长序列数就是栈的大小 */
        cout << top << endl;
      }
        return 0;
    }
  • 相关阅读:
    auto关键字
    关闭vs的编译警告
    windows C++删除非空文件夹
    vs相同变量高亮显示
    梯度下降算法到logistic回归
    ubuntu 按键替换 Control_R to Left
    git 删除分之以及删除文件夹
    迄今为止计算机视觉领域超有实力的研究人物主页
    DeepLearning——CNN
    利用积分图进行均值滤波
  • 原文地址:https://www.cnblogs.com/kls123/p/7783694.html
Copyright © 2011-2022 走看看