zoukankan      html  css  js  c++  java
  • AcWing 896. 最长上升子序列 II

    题目传送门

    1、与原始版本区别

    原始版本:\(1≤N≤1000\),本题要求:\(1≤N≤100000\)

    \(N\)的数据范围大了\(100\)倍,原始版本的题的时间复杂度是\(O(N^2)\),\(1000^2=1000000\),是\(1e6\),是可以\(1\)秒过的,但如果是\(100000^2=10000000000\),是\(1e10\),超时,需要要优化~

    2、题解

    #include <bits/stdc++.h>
    
    using namespace std;
    const int N = 100010;
    /*
    例 n: 7
    arr : 3 1 2 1 8 5 6
    
    stk : 3
    
    1 比 3 小
    stk : 1
    
    2 比 1 大
    stk : 1 2
    
    1 比 2 小
    stk : 1 2
    
    8 比 2 大
    stk : 1 2 8
    
    5 比 8 小
    stk : 1 2 5
    
    6 比 5 大
    stk : 1 2 5 6
    
    stk 的长度就是最长递增子序列的长度
    
    */
    int n, a[N];
    //单调栈
    int stk[N], idx;
    
    int main() {
        cin >> n;
        for (int i = 1; i <= n; i++) cin >> a[i];
    
        //第一个数字入栈
        stk[++idx] = a[1];
    
        //讨论后面的n-1个数字
        for (int i = 2; i <= n; i++) {
            //如果该元素大于栈顶元素,将该元素入栈(对后序数字可能有用)
            if (a[i] > stk[idx]) stk[++idx] = a[i];
                //替换掉第一个大于或者等于这个数字的那个数
            else *lower_bound(stk + 1, stk + 1 + idx, a[i]) = a[i];
        }
        printf("%d\n", idx);
        return 0;
    }
    
    

    3、解题思路

    栈内记录:【长度为\(i+1\)的递增子串中,末尾元素最小的是\(stk[i]\)】。

    理解了这个问题以后就知道为什么新进来的元素要不就在末尾增加,要不就替代第一个大于等于它元素的位置。

    这里的【替换】就蕴含了一个贪心的思想,对于同样长度的子串,我当然希望它的末端越小越好,这样以后我也有更多机会拓展。

  • 相关阅读:
    keil编译器从ac5迁移到ac6
    分享一个简单易用的软件定时器模块(MultiTimer)——基于keil+stm32f103zet+hal库(裸机实现)
    PID动图——很形象
    jlink之j-scope使用
    Keil的RTX特性
    Keil5创建基于RTX的STM32工程(转载+自己的体会)
    CMSIS-RTOS 简介
    Chapter 3 Phenomenon——13
    Chapter 3 Phenomenon——12
    Chapter 3 Phenomenon——11
  • 原文地址:https://www.cnblogs.com/littlehb/p/15429000.html
Copyright © 2011-2022 走看看