首页 > 其他分享 >最长上升子序列

最长上升子序列

时间:2023-10-09 22:59:23浏览次数:29  
标签:int max mx ++ 序列 上升 最长

最长上升子序列是使用动态规划求解的经典题目。
B3637 最长上升子序列

1. 题目描述

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

2. 动态规划

使用动态规划的核心是构造状态转移表达式,先来看看这道题目是如何定义状态及转移方程的。
定义f[i]表示以w[i]结尾的最大上升序列长度,则在w[i] > w[j]时,f[i] = max(f[i], f[j] + 1),j=0,1,2,...,i-1。上面这种情况的时候要更新状态是不难理解的,但是这也导致f[i]是由小于i的最优解通过增加w[i]产生的,有没有可能f[i]是由小于i的非最优解产生的呢,也就是说在w[i] <= w[j]时,f[j]也存在信息,可以用于产生最优解,其实仔细想一下这种情况就是去除w[j]后的上升子序列加上w[i]构成的,那么一定会存在一个对应于w[i] > w[q],并使用f[i] = max(f[i], f[q] + 1)进行更新,所以在w[i] <= w[j]时是不用再进行更新的。
下面看一下代码。

#include<iostream>
#include<algorithm>
using namespace std;

int n;
int w[5010]; //输入序列
int f[5010]; //状态记录

int main() {
    ios::sync_with_stdio(0);
    cin >> n;
    for(int i; i < n; i ++) {
        cin >> w[i];
    }
    int mx = 1;
    for(int i = 1; i < n; i ++) {
        f[i] = 1;
        for(int j = 0; j < i; j ++) {
            if(w[i] > w[j]) {
                f[i] = max(f[i], f[j] + 1);
            }
        }
        mx = max(mx, f[i]);
    }
    cout << mx;
    return 0;
}

动态规划的代码总是很简洁明了,但是想出来思路就很难,特别是第一次遇到某个题目。

3. 输出一个最长上升子序列

根据f[n]状态记录数组的定义,可以从小到大依次输出状态记录分别为mx,mx-1,...,1。最长上升子序列显然是可能不唯一的,下面的代码只输出一个。

int mx = 1, pos = 0;
for(int i = 0; i < n; i ++) {
    if(mx <= f[i]) {
        mx = f[i];
        pos = i;
    }
}
// 输出一个最长上升子序列
int *num = new int(mx);
num[0] = w[pos];
int cnt = 0;
for(int i = pos - 1; i >= 0; i --) {
    if(f[i] == mx - 1) {
        num[++ cnt] = w[i];
        mx --;
    }
}
for(int i = cnt; i >= 0; i --) {
    if(i < cnt) {
        cout << ' ';
    }
    cout << num[i];
}

参考资料

  1. 最长上升子序列(序列长度+序列输出)

标签:int,max,mx,++,序列,上升,最长
From: https://www.cnblogs.com/zhangdoudou/p/17753398.html

相关文章

  • P3970 [TJOI2014] 上升子序列
    题目先将\(a[i]\)离散化。设\(f[i]\)表示以数字\(i\)结尾的上升子序列数量。则有\(f[i]=\sum_{j=1}^{i-1}f[j]\)。考虑用线段树实时维护\(f[j]\),就可以\(logn\)查询。扫一遍整个序列,因为不能算重复,所以\(ans\)先减去上一次见到\(a[i]\)时的贡献\(f[a[i]]\),再......
  • R语言ARMA-GARCH模型金融产品价格实证分析黄金价格时间序列
    全文链接:http://tecdat.cn/?p=32677原文出处:拓端数据部落公众号最近我们被客户要求撰写关于ARMA-GARCH的研究报告,包括一些图形和统计输出。研究黄金价格的动态演变过程至关重要。文中以黄金交易市场下午定盘价格为基础,帮助客户利用时间序列的相关理论,建立了黄金价格的ARMA-GA......
  • 利用 Javascript 生成数字序列
    <!DOCTYPEhtml><html><head><title>生成数字序列</title></head><body><h1>Element对象之innerHTML属性</h1><pid="demo"onclick="myFunction()">点击生成数字序列</p><script>funct......
  • 《动手学深度学习 Pytorch版》 8.1 序列模型
    到目前为止,我们遇到的数据主要是表格数据和图像数据,并且所有样本都是独立同分布的。然而,大多数的数据并非如此。比如语句中的单词、视频中的帧以及音频信号,都是有顺序的。简言之,如果说卷积神经网络可以有效地处理空间信息,那么本章的循环神经网络(recurrentneuralnetwork,RNN)则可......
  • pytorch(8-1) 循环神经网络 序列模型
    https://zh.d2l.ai/chapter_recurrent-neural-networks/sequence.html     #%matplotlibinlineimporttorchfromtorchimportnnfromd2limporttorchasd2lfromAPI_Drawimport*T=1000#总共产生1000个点#time[0,1...,999]time=torch.arange(......
  • Unity 通信方案 - 使用 Google Protobuf 序列化数据
    1.下载和编译1.1下载ProtoBuf源文件从github下载最新的protoBuf库,如下图所示 Releases·protocolbuffers/protobuf(github.com)1.2编译dll和导入解压后打开/scharp/src中的sln工程文件 选择Release,Google.Protobuf,之后在生成中生成文件在......
  • 数据结构的关键码序列的理解概述
    1、关键码序列的理解所谓关键码序列,就是出现在二叉排序树中的,对二叉排序树的各个结点进行排序的一个结点序列。依据左子树的各个结点的值都小于父结点的值,右子树的各个结点的值都大于父结点的值的条件进行排序。2、习题解决一般都是给我们一个二叉排序树的图,让我们去判断选......
  • Mysql 分布式序列算法
    接上文Mysql分库分表1.分布式序列简介在分布式系统下,怎么保证ID的生成满足以上需求?ShardingJDBC支持以上两种算法自动生成ID。这里,使用ShardingJDBC让主键ID以雪花算法进行生成,首先配置数据库,因为默认的注解id是int类型,装不下64位,需要进行修改:#在本地和远端服务器数据......
  • Excel快速下拉填充序列至10000行
    问题:想要下拉输入的数据递增得到1、2、3……10000,但是手动下拉太累解决:1.如在A1单元格输入1,在A2单元格输入22.选中A2单元格,在上方名称框中填写A2:A1000,回车,此时将选中A2:A10003.在编辑栏中填写=A1+1,按Ctrl+回车,便可得到一万条递增数据1、2、3……100004.同上效果,可在编辑栏......
  • leet code 3. 无重复字符的最长子串
    leetcode3.无重复字符的最长子串题目描述给定一个字符串s,请你找出其中不含有重复字符的**最长子串**的长度。示例1:输入:s="abcabcbb"输出:3解释:因为无重复字符的最长子串是"abc",所以其长度为3。示例2:输入:s="bbbbb"输出:1解释:因为无重复字符的最......