【序列dp】最长上升子序列(一)

news2024/11/23 13:26:37

文章目录

    • 最长上升子序列-序列dp
      • 概览
      • 895 最长上升子序列-O(n^2)
      • 1017 怪盗基德的滑翔翼
      • 1014 登山
      • 482 合唱队形
      • 1012 友好城市

最长上升子序列-序列dp

  • 什么是序列相关的 DP ?
  • 序列相关 DP,顾名思义,就是将动态规划算法用于数组或者字符串上,进行相关具体问题的求解
  • 何时可以使用序列相关的 DP?
  • 当题目求解以下内容时,可以考虑使用序列相关的 DP
  • 给定两个字符串,求最长/大的某种值
  • 给定数组,求最长/大的某种值

此外,在使用序列相关的 DP 的时候,我们还需要注意到,这是一类的动态规划,所以需要满足动态规划的两种重要条件
最长上升子序列问题是一个经典的动态规划问题,目标是在给定序列中找到一个最长的升序子序列。

问题描述:
给定一个序列,要求找到其中最长的一个升序子序列。也就是说,要找到一个子序列,使得其中的元素按照从小到大的顺序排列,并且长度最长。

解决方法:
一种常用的动态规划方法来解决最长上升子序列问题是使用一个辅助数组dp。dp[i]表示以第i个元素结尾的最长上升子序列的长度。

具体步骤如下:

  1. 初始化dp数组为1,所有的元素初始都有一个长度为1的子序列。
  2. 对于每个位置i,从0到i-1遍历前面的元素j:
    • 如果第i个元素大于第j个元素,说明可以将第i个元素添加到以第j个元素结尾的子序列中,形成一个更长的子序列。
      • 此时更新dp[i] = max(dp[i], dp[j] + 1),表示以第i个元素结尾的子序列的长度。
  3. 遍历所有的dp[i],找到其中的最大值max_length,即为最长上升子序列的长度。

最后,根据dp数组的记录,可以逆向构造最长上升子序列的元素。

总结:
最长上升子序列问题可以通过动态规划的方法解决,使用dp数组记录以每个位置结尾的最长上升子序列长度,通过逐个比较元素大小,不断更新dp数组。最终得到最长上升子序列的长度,及其中的元素。这个问题是经典的算法问题,在实际应用中有广泛的应用。

概览

在这里插入图片描述

895 最长上升子序列-O(n^2)

在这里插入图片描述

集合表示:所有以a[i]结尾的最长上升子序列

属性为Max即长度的最大值

考虑如何计算,一般考虑最后一个点,可以取

空,a[0],a[1],…,a[i-1]

但是有的区间为空,当a[k] >= a[i]时,即不满足上升子序列

计算时:a[i]=Math.max(满足条件的a[k])

最终答案,遍历所有下标,选取最长的上升子序列

package acwing_plus.动规.最长上升子序列;

import java.util.Scanner;

/**
 * @author ty
 * @create 2023-03-30 21:35
 */
public class 最长上升子序列 {
    static int N = 1010;
    static int[] a = new int[N];
    static int[] f = new int[N];
    static int n;
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        n = sc.nextInt();
        for (int i = 1;i <= n;i++) {
            a[i] = sc.nextInt();
        }
        for (int i = 1;i <= n;i++) {
            f[i] = 1;
            for (int j = 1;j < i;j++) {
                if (a[i] > a[j]) {
                    f[i] = Math.max(f[j] + 1,f[i]);
                }
            }
        }
        int res = 0;
        for (int i = 1;i <= n;i++) {
            //res是所有不同a[i]结尾的最大值
            res = Math.max(res,f[i]);
        }
        System.out.println(res);
    }
}

1017 怪盗基德的滑翔翼

在这里插入图片描述

在这里插入图片描述

LIS的双向求解,主要掌握求最长下降序列,即反向求解最长上升序列

package acwing_plus.动规.最长上升子序列;

import java.util.Scanner;

/**
 * @author ty
 * @create 2023-03-30 21:57
 */
public class 怪盗基德 {
    static int N = 110;
    static int n;
    static int[] a = new int[N];
    static int[] f = new int[N];
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int T = sc.nextInt();
        while (T-- > 0 ) {
            n = sc.nextInt();
            for (int i = 1;i <= n;i++) {
                a[i] = sc.nextInt();
            }
            //正向求解LIS问题
            int res = 0;
            for (int i = 1;i <= n;i++) {
                f[i] = 1;
                for (int j = 1;j < i;j++) {
                    if (a[j] < a[i]){
                        f[i] = Math.max(f[j] + 1,f[i]);
                    }
                }
                res = Math.max(res,f[i]);
            }
            //反向求解LIS
            for (int i = n;i >= 1;i--) {
                f[i] = 1;
                for (int j = n;j > i;j--) {
                    if (a[i] > a[j]) {
                        f[i] = Math.max(f[i],f[j] + 1);
                    }
                }
                res = Math.max(f[i],res);
            }
            System.out.println(res);
        }
    }
}

1014 登山

在这里插入图片描述

在这里插入图片描述

自己实现,由怪盗基德思想实现

package acwing_plus.动规.最长上升子序列;

import java.util.Scanner;

/**
 * @author ty
 * @create 2023-03-30 23:10
 */
public class 登山 {
    static int N = 1010;
    static int[] a = new int[N];
    static int[] l = new int[N];
    static int[] r = new int[N];
    static int n;
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        n = sc.nextInt();
        for (int i = 1;i <= n;i++ ) {
            a[i] = sc.nextInt();
        }
        int res = 0;
        //求最长下降子序列长度
        for (int i = n;i >= 1;i-- ) {
            r[i] = 1;
            for (int j = n;j > i;j--) {
                if (a[i] > a[j]) {
                    r[i] = Math.max(r[j] + 1,r[i]);
                }
            }
        }
        //求最长上升子序列长度
        for (int i = 1;i <= n;i++) {
            l[i] = 1;
            for (int j = 1;j < i;j++) {
                if (a[i] > a[j]) {
                    l[i] = Math.max(l[i],l[j] + 1);
                }
            }
        }
        for (int i = 1;i <= n;i++) {
            res = Math.max(l[i]+r[i] - 1,res);
        }
        System.out.println(res);
    }
}

482 合唱队形

在这里插入图片描述

登山的变体,求整个队列个数-max(每个点的最大上升序列+最大下降序列-1)

package acwing_plus.动规.最长上升子序列;

import java.util.Scanner;

/**
 * @author ty
 * @create 2023-03-31 0:36
 */
public class 合唱队形 {
    static int N = 110;
    static int n;
    static int[] a = new int[N];
    static int[] l = new int[N];
    static int[] r = new int[N];
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        n = sc.nextInt();
        for (int i = 1;i <= n;i++) {
            a[i] = sc.nextInt();
        }
        for (int i = 1;i <= n;i++) {
            l[i] = 1;
            for (int j = 1;j < i;j++) {
                if (a[i] > a[j]) {
                    l[i] = Math.max(l[i],l[j] + 1);
                }
            }
        }
        for (int i = n;i >= 1;i--) {
            r[i] = 1;
            for (int j = n;j >= i;j--) {
                if (a[i] > a[j]) {
                    r[i] = Math.max(r[i],r[j] + 1);
                }
            }
        }
        int res = 0;
        for (int i = 1;i <= n;i++) {
            res =  Math.max(res,l[i] + r[i] -1);
        }
        System.out.println(n - res);
    }
}

1012 友好城市

在这里插入图片描述

在这里插入图片描述

package acwing_plus.动规.最长上升子序列;

import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;

/**
 * @author ty
 * @create 2023-03-31 9:40
 */
public class 友好城市 {
    static int N = 5010;
    static Edge[] a = new Edge[N];
    static int[] f = new int[N];
    static int INF = (int)-1e9;
    static class Edge {
        int u,d;

        public Edge(int u, int d) {
            this.u = u;
            this.d = d;
        }
    }
    static int n;
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        n = sc.nextInt();
        for (int i = 1;i <= n;i++) {
            int x = sc.nextInt();
            int y = sc.nextInt();
            a[i] = new Edge(x,y);
        }
        //按下面排好序
        Arrays.sort(a, 1, n + 1, new Comparator<Edge>() {
            @Override
            public int compare(Edge o1, Edge o2) {
                return o1.d - o2.d;
            }
        });
        //上面的点一定是上升序列,才能成立
        //此处寻找最长上升子序列
        for (int i = 1;i <= n;i++) {
            f[i] = 1;
            for (int j = 1;j < i;j++) {
                if (a[i].u > a[j].u) {
                    f[i] = Math.max(f[i],f[j] + 1);
                }
            }
        }
        int res = 0;
        for (int i = 1;i <= n;i++) {
            res = Math.max(res,f[i]);
        }
        System.out.println(res);
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/667651.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

textgen教程(持续更新ing...)

诸神缄默不语-个人CSDN博文目录 官方GitHub项目&#xff1a;shibing624/textgen: TextGen: Implementation of Text Generation models, include LLaMA, BLOOM, GPT2, BART, T5, SongNet and so on. 文本生成模型&#xff0c;实现了包括LLaMA&#xff0c;ChatGLM&#xff0c;B…

C++课程学习记录

目录 1. 前置说明2. 二叉树的模拟2.1 参考资料2.2 二叉树的构建2.2.1 递归构建2.2.2 迭代构建 2.3 二叉树的遍历2.4 二叉树的应用 3. 继承与派生3.1 最简单的生死3.2 动态申请空间的生死3.3 继承中的protectd权限3.4 三种继承方式3.5 修改某些继承成员的继承类型3.6 多级派生3.…

C++57个入门知识点_番外1_C++指针偏移在类中的应用及指针偏移原理

这是对C指针偏移介绍比较好的博文&#xff0c;但是比较分散&#xff0c;我把其进行了整理&#xff0c;原博文地址请见最后&#xff0c;讲的很详细。 C57个入门知识点_番外1_C指针偏移在类中的应用及指针偏移原理 1. C指针偏移原理2. C显示十进制内存地址&#xff08;不用理解&…

AQS原理

目录 一、原理概述二、AQS 对资源的共享方式三、AQS底层使用了模板方法模式四、使用demo&#xff0c;使用AQS实现不可重入锁五、AQS使用到的几个框架 一、原理概述 AQS全称是 AbstractQueuedSynchronizer&#xff0c;是阻塞式锁和相关的同步器工具的框架 AQS核心思想是&#…

Appian低代码平台

国外老牌低代码开发平台Appian Appian在国内用的比较少&#xff0c;资料也很匮乏。需要自己主动去官网寻找。 Appian 学习平台 进入Appian Community可以选择学习路径&#xff0c;可以选择适合自己的学习路径&#xff1b;我选择的是Builder路径&#xff0c; 看了足足80个小…

opencv检测二维码和条形码

文章目录 1 excel制作简单二维码2 识别二维码和条形码2.1 相关库2.2 decode解码2.3 圈出二维码的位置2.4 判断二维码是否授权 3 完整代码3.1 使用图片进行识别3.2 使用摄像头实时识别 4 总结 1 excel制作简单二维码 使用excel可以实现制作二维码&#xff0c;但只能实现做英文和…

基于51单片机的简易电子琴设计

目录 摘 要 基于51单片机的简易电子琴设计 一、系统设计 1、项目概要 2.设计任务和基本要求 二、硬件设计 1、硬件设计概要 2、时钟振荡电路模块 3.复位电路模块 5.数码管电路模块 6.蜂鸣器模块 7、乐曲切换电路模块 三、软件原理 四、软件流程图 五、代码实现 …

解析Transformer基本结构与实现

1.基本结构 ​ Transformer总体架构可分为4个部分&#xff1a; 输入部分-输出部分-编码器部分-解码器部分 输入部分包含&#xff1a; 原文本嵌入层&#xff08;Input embedding&#xff09;及其位置编码(position encoding)目标文本嵌入层及其位置编码器 文本嵌入层的作…

TCP/UDP协议重温三次握手四次挥手 简单笔记

术语储备&#xff1a; SYN&#xff1a;同步位 &#xff1b;SYN1,表示进行一个连接请求 ACK&#xff1a;确认位 &#xff1b;ACK1,确认有效 ACK0&#xff0c;确认无效 ack : 确认号 &#xff1b;对方发送序号1 seq &#xff1a; 序号 ; 标识从TCP发端向TCP收端发送的数据字节流 …

基于JPA的Repository使用详解

Spring Data JPA Spring Data是Spring提供的操作数据的框架&#xff0c;Spring Data JPA是Spring Data的一个模块&#xff0c;通过Spring data 基于jpa标准操作数据的模块。 Spring Data的核心能力&#xff0c;就是基于JPA操作数据&#xff0c;并且可以简化操作持久层的代码。…

BLOND:ISH VoxEdit 创作大赛来啦!

准备好随着 BLOND:ISH 的节拍释放你们的创造力和节奏&#xff0c;因为我们将举办一场与众不同的刺激比赛。你们可以在 BLOND:ISH VoxEdit 大赛中展示你们的才华并赢得 SAND 奖励&#xff01; &#x1f3dd;️ 比赛主题&#xff1a;ABRA 夏日派对 &#x1f3dd;️ 释放你们的想象…

【Python学习】—Python基础语法(二)

文章目录 【Python学习】—Python基础语法&#xff08;二&#xff09;一、字面量二、注释三、变量四、数据类型五、数据类型转换六、标识符七、运算符八、字符串扩展九、获取键盘输入 【Python学习】—Python基础语法&#xff08;二&#xff09; 一、字面量 字面量&#xff1…

文件类型识别的实现思路

一些网络设备&#xff0c;比如防火墙或者审计系统&#xff0c;一般都有文件过滤的功能&#xff0c;可以对用户上网传输的文件进行过滤&#xff0c;比如可以限制用户通过ftp下载word文档&#xff0c;也就是文件类型为doc或者docx的文件。 那么文件过滤的功能是怎么实现呢&#…

2023年计算机专业还值得无脑梭哈吗——计算机类专业在读一年学生个人分享

长忆观潮&#xff0c;满郭人争江上望。来疑沧海尽成空&#xff0c;万面鼓声中。 弄潮儿向涛头立&#xff0c;手把红旗旗不湿。别来几向梦中看&#xff0c;梦觉尚心寒。 IT 界每隔几年就有一波浪潮或者泡沫&#xff0c;新的一波大潮已经打过来了&#xff0c;躲&#xff1f;能跑多…

【计算机视觉】CVPR 23 新论文 | 异常检测最新改进方法:DeSTSeg

文章目录 一、导读二、背景2.1 主要贡献2.2 网络介绍&#xff1a;DeSTSeg 三、方法3.1 Synthetic Anomaly Generation 合成异常生成3.2 Denoising Student-Teacher Network 去噪教师学生网络3.3 Segmentation Network 分割网络 四、实验结果 一、导读 DeSTSeg: Segmentation G…

数字图像处理【10】直方图反向投影与模板匹配

本篇简单描述直方图在图像处理中典型的应用场景&#xff0c;属于是比较老旧的应用技术&#xff0c;但不妨拿出来再学习&#xff0c;温故而知新&#xff0c;为新知识做一个铺垫。 直方图反向投影&#xff08;Back Projection&#xff09; 还记得之前学习过的图像直方图的计算/…

Knowledge Distillation of Large Language Models

这是大模型系列模型的文章&#xff0c;针对《Knowledge Distillation of Large Language Models》的翻译。 大模型的知识蒸馏 摘要1 引言2 方法2.1 MiniLLM&#xff1a;利用逆向KLD进行知识蒸馏2.2 策略梯度优化2.3 训练算法 3 实验3.1 实验设置3.2 结果3.3 分析3.4 消融实验 …

源码编译安装LAMP——LAMP+DISCUZ论坛搭建

文章目录 一.Apache1.什么是apache2.apache的主要特点3.apache的软件版本4.编译安装优点5.安装服务的一般步骤 二.LAMP简介与概述1.LAMP平台概述2.构建LAMP平台顺序3.各组件的主要作用 三.LAMPDISCUZ论坛搭建1.部署Apache1.1 下载apache相关安装包放入服务器中1.2 解压apache的…

数学公式识别(Mathpix + pix2tex)

文章目录 数学公式识别&#xff08;Mathpix pix2tex&#xff09;1. 下载安装2. 如何使用3. 限制4. 替代品4.1 pix2tex - LaTeX OCR4.2 pix2tex&#xff08;网页版&#xff09;4.3 Simple Tex OCR 数学公式识别&#xff08;Mathpix pix2tex&#xff09; 当我们看论文时&#…

2023软件工程中各种图在现代企业级开发中的使用频率

概览 系统流程图 ✔ 数据流图 不常用 ER图 ✔ 状态转换图 ✔ Warnier图 不常用 IPO图 不常用 Petri网 不常用 层次方框图 不常用 层次图 a.k.a. H图 ✔ 1,层次图描绘软件的层次结构.层层次方框图描绘的是数据结构。 2,层次图的方框表示模块或子模块。层次方框图的方框表示数据结…