zoukankan      html  css  js  c++  java
  • 贪心法解最长上升子序列

    题意

    给定一个长度为(N)的数列,求数值严格单调递增的子序列的长度最长是多少。

    数据范围

    (1 leq N leq 100000)

    思路

    维护一个数组 nums,要求这个数组里的元素在数值上是严格递增的。

    遍历每一个数,如果这个数比数组里的最后一个数更大,那么就将这个数插入数组的最后;反之,替换掉数组中第一个大于等于这个数的元素。

    最后的答案就是数组中元素的个数。

    对于这个贪心策略,考虑一种理解方式:这个数组不用于记录最终的最长子序列,而是以 nums[i] 结尾的子序列长度最长为 i,即长度为 i 的递增序列中,末尾元素最小的是 nums[i]。

    理解了上面这一点,正确性就显然了。

    代码

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <vector>
    
    using namespace std;
    
    const int N = 100010;
    
    int n;
    vector<int> nums;
    
    int main()
    {
        scanf("%d", &n);
        int x;
        scanf("%d", &x);
        nums.push_back(x);
        for(int i = 2; i <= n; i ++) {
            scanf("%d", &x);
            if(x > nums[nums.size() - 1]) nums.push_back(x);
            else nums[lower_bound(nums.begin(), nums.end(), x) - nums.begin()] = x;
        }
        // lower_bound: 大于等于 x 的第一个数
        // upper_bound: 大于 x 的第一个数
        printf("%d
    ", nums.size());
        return 0;
    }
    
  • 相关阅读:
    js获取当前时间日期
    js操作Cookie
    C#常用正则表达式
    jquery操作select、radio、checkbox表单元素
    js实现页面跳转的几种方式
    js获取页面宽高大小
    c++写一个类后编译发现class重定义
    vtkMultiThreader坑爹吗?
    vtkStandardNewMacro()出现错误的问题
    转:将CFormView嵌入到CDockablePane中
  • 原文地址:https://www.cnblogs.com/miraclepbc/p/14432351.html
Copyright © 2011-2022 走看看