首页 > 其他分享 >NC91 最长上升子序列(三)

NC91 最长上升子序列(三)

时间:2024-01-17 17:23:08浏览次数:32  
标签:arr vector end len maxlen NC91 序列 最长 dp

https://www.nowcoder.com/practice/9cf027bf54714ad889d4f30ff0ae5481?tpId=117&rp=1&ru=%2Fexam%2Foj&qru=%2Fexam%2Foj&sourceUrl=%2Fexam%2Foj%3Fpage%3D1%26tab%3D%25E7%25AE%2597%25E6%25B3%2595%25E7%25AF%2587%26topicId%3D117&difficulty=&judgeStatus=&tags=&title=&gioEnter=menu

动态规划+二分:

dp[i]:dp数组表示(在数组dp中)以i结尾的最长序列的元素。

例如 arr = [ 1, 3, 2 ] 则 dp = [ 1, 2 ] 即长度为1的序列最后的元素为1,长度为2的序列最后元素为2。

maxlen[i]:表示(在数组arr中)以i结尾的最长序列的长度。

算法流程:我们在遍历arr的时候

  1. 当arr[i] >dp.back() 此时把arr[i]放入dp,表示我们找到了一条更长的子序列,并更新对应i下maxlen的长度。
  2. 否则,需要找到dp数组里面第一个大于等于arr[i]的元素,更新该元素。并且插入maxlen为找到这个元素所对应的子序列长度

这里以 arr = [ 1,4,6,3 ]为例:

当放入1:dp[1],max[1]

当放入4:dp[1,4],max[1,2]

当放入6:dp[1,4,6],max[1,2,3] //这里对应算法流程的第一步

当放入3:dp[1,3,6],max[1,2,3,2] //这里对应算法流程的第二步,我们很容易发现当前的dp数组并不是一个正确的序列,所以dp并不是最后的结果数组,dp数组只是表示长度为n长度最长序列的最后元素,也就是最长为2的最后元素为3,最长为3的最后元素为6

最后我们逆序遍历max数组,从dp的长度开始,该例中为3,找到各个位置的元素,这里逆序的原因我们很容易想到,是因为后面的元素,我们都是往字典序小的方向更新的。


#include <algorithm>
#include <cstdio>
#include <vector>
class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * retrun the longest increasing subsequence
     * @param arr int整型vector the array
     * @return int整型vector
     */

    vector<int> LIS(vector<int>& arr) {
        // write code here
        vector<int> res;
        const int len = arr.size();
        if (!len) return res;
        vector<int> dp;
        vector<int> maxlen;
        dp.emplace_back(arr[0]);
        maxlen.emplace_back(1);
        for (int i = 1; i < len; i++) {
            if (arr[i] > dp.back()) {
                dp.emplace_back(arr[i]);
                maxlen.emplace_back(dp.size());
            }
            else {
                int index = lower_bound(dp.begin(), dp.end(), arr[i]) - dp.begin();
                dp[index] = arr[i];
                maxlen.emplace_back(index + 1);
            }
        }
        int end = len - 1;
        while (maxlen[end] != dp.size()) {
            end--;
        }
        res.resize(dp.size());
        int cur_len = dp.size();
        while (end >= 0) {
            if (maxlen[end] == cur_len) {
                res[cur_len - 1] = arr[end];
                cur_len--;
            }
            end--;
        }
        return res;
    }
};

标签:arr,vector,end,len,maxlen,NC91,序列,最长,dp
From: https://www.cnblogs.com/lihaoxiang/p/17970533

相关文章

  • 「云渲染科普」blender如何导出序列帧与序列帧动画
    blender是不少人都在使用的动画建模软件,工具免费使用,且支持多种渲染器插件,能够为用户制作出完整得动画人物、场景建模,那么blender中去如何导出序列帧与序列帧动画呢?下面一起来看看吧。一、blender怎么导出序列帧1、先设置输出格式为:PNG,在点击ctrlF12渲染动画,等待序列帧图像......
  • Python pickle 二进制序列化和反序列化 - 数据持久化
    模块pickle实现了对一个Python对象结构的二进制序列化和反序列化。"pickling"是将Python对象及其所拥有的层次结构转化为一个字节流的过程,而"unpickling"是相反的操作,会将(来自一个binaryfile或者bytes-likeobject的)字节流转化回一个对象层次结构。pickling(和unp......
  • P2572 [SCOI2010] 序列操作 题解
    题解:序列操作比较综合的ds题,综合了线段树常见的几种操作:维护最大子段和、区间翻转、区间求和、区间覆盖。维护子段和常见的我们维护三类东西:前缀最长连续段、后缀最长连续段、当前区间上的最大子段和。在pushUp时,对于一个区间的前后缀最值首先等于左右子树的最长前后缀,......
  • 无涯教程-SQL - Sequences(序列)
    序列是按需生成的一组整数1、2、3,...。序列在数据库中经常使用,因为许多应用程序要求表中的每一行都包含唯一值。本章介绍如何在MySQL中使用序列。AUTO_INCREMENT列MySQL中使用序列的最简单方法是将一列定义为AUTO_INCREMENT,其余部分留给MySQL处理。试试下面的例子,这将创建一......
  • 机器学习-概率图模型系列-隐含马尔科夫-观测序列的概率计算-35
    目录1.暴力求解法2.前向算法求HMM观测序列的概率3.从后往前推后向算法1.暴力求解法任意一条路径都有可能得到需要的观测结果:如果我们的隐藏状态数N非常多的那就麻烦了,此时我们预测状态有NT种组合,算法的时间复杂度是O(TNT)阶的2.前向算法求HMM观测序列的概率在前向算......
  • c# csharp 对象序列化
    对象序列化要将一个序列化对象存储起来,您可以使用C#中的序列化和反序列化功能。以下是一个示例代码,它演示了如何将一个序列化对象存储到文件中:usingSystem;usingSystem.IO;usingSystem.Runtime.Serialization.Formatters.Binary;namespaceMyNamespace{[Serializab......
  • 配置redisTemplate序列化,解决乱码与反序列化失败
    /***@projectName:MultiModuleDemo*@package:com.example.config*@className:RedisConfig*@description:TODO(配置RedisTemplate序列化)*@date:2023/12/1821:08*@version:1.0*/@ConfigurationpublicclassRedisConfig{@BeanpublicRedi......
  • C# 对象序列化 单元测试 .netframework
    对象序列化以及单元测试F:\song\netframework_serialize\netframework_serialize\Program.csusingnetframework_serialize.Animal;usingSystem;usingSystem.Collections.Generic;usingSystem.IO;usingSystem.Linq;usingSystem.Runtime.Serialization.Formatters.Bina......
  • 无重复字符的最长子串
    给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。示例 1:输入:s="abcabcbb"输出:3解释:因为无重复字符的最长子串是"abc",所以其长度为3。示例2:输入:s="bbbbb"输出:1解释:因为无重复字符的最长子串是"b",所以其长度为1。示例3:......
  • 无重复字符的最长子串2
    classSolution{public:intlengthOfLongestSubstring(strings){//哈希集合,记录每个字符是否出现过unordered_set<char>occ;intn=s.size();//右指针,初始值为-1,相当于我们在字符串的左边界的左侧,还没有开始移动int......