【算法】子集(LIS最长上升子序列)

文章目录

    • 题目
    • 输入描述
    • 输出描述
    • 示例
    • 分析
    • 思路
    • 最长递增子序列
    • dp解法(2/10)
    • binarySearch + 贪心(AC)

题目

小强现在有 n n n个物品,每个物品有两种属性 x i x^i xi y i y^i yi。他想要从中挑出尽可能多的物品满足以下条件:对于任意两个物品 i i i j j j,满足 x i < x j 且 y i < y j x^i < x^j 且 y^i < y^j xi<xjyi<yj或者 x i > x j 且 y i > y j x^i > x^j 且 y^i > y^j xi>xjyi>yj. 问最多能够挑出多少物品

输入描述

第一行输入一个正整数 T T T.表示有 T T T组数据.
对于每组数据,第一行输入一个正整数 n n n.表示物品个数.
接下来两行,每行有 n n n个整数.
第一行表示 n n n个节点的 x x x属性.
第二行表示 n n n个节点的 y y y属性.

1 < = T < = 10 2 < = n < = 100000 0 < = x , y < = 1000000000 1 <= T <= 10\\ 2 <= n <= 100000\\ 0<= x, y <= 1000000000 1<=T<=102<=n<=1000000<=x,y<=1000000000

输出描述

输出 T T T行,每一行对应每组数据的输出.

示例

输入例子:
2
3
1 3 2
0 2 3
4
1 5 4 2
10 32 19 21
输出例子:
2
3

分析

这题看上去比较绕,我们先以示例入手,简单拆解一下

在这里插入图片描述

现在,我们将目光聚焦于绿框部分,如下图所示

在这里插入图片描述

我们需要选出若干个红框,使得红框组成x属性严格递增的序列时,同时保证y属性也严格递增。且选择红框数量尽可能大

例如,我们选择1,3红框,能够实现双递增序列:
1 -> 3
0 -> 2

2,3红框无法实现双递增序列:
2 -> 3
3 -> 2
(红框元素被绑定死,不能随意组合x,y中任意下标的元素)

如果我们选择1,2,3红框,无法实现递增序列,因为2,3无法形成双递增序列

思路

  1. 设计数据结构,将x,y对应下标元素组合再一起。例如构建如下数据结构
    class Node {public int x;public int y;
    }
    Node[] nodes = new Node[N];
    
  2. 对Node的x属性排序,保证nodes按照x非递减排序
  3. 对排序后的y属性进行筛选,选出最长递增子序列

tip: 此处需要注意,nodes无法按照x严格递增。因为可能存在若干个具有相同x值的node。因此在排序时,如果x相同,需要按照y降序排序。因为这样在对y进行筛选时,在x相同情况下,只能选择一个y最为最终序列。
例如:
1 9 9
3 8 7
最终会只能选择3, 8 | 3,7。如果x相同,但是不按照y降序,则可能会选择3,7,8.导致重复选择相同的x,而无法保证x严格递增

最长递增子序列

目前有两种解法

  1. dp
  2. binarySearch + 贪心

dp和bs算法已经有非常多成熟的文章,感兴趣的读者可以自行了解上述两篇文章,本文只给出ac代码

dp解法(2/10)

import java.util.*;public class Main {static class Node {public int x;public int y;public Node() {}}public static void main(String[] args) {Scanner sc = new Scanner(System.in);int T = sc.nextInt();int n;for (int i = 0; i < T; ++i) {n = sc.nextInt();Node[] x = new Node[n];// 存储 x - yfor (int j = 0; j < n; ++j) {Node node = new Node();node.x = sc.nextInt();x[j] = node;}for (int j = 0; j < n; ++j) {x[j].y = sc.nextInt();}// 排序Arrays.sort(x, (Node a, Node b) -> {if (a.x != b.x) return a.x - b.x;else return - (a.y - b.y);});int[] y = new int[n];for (int j = 0; j < n; ++j) {y[j] = x[j].y;}// 求最长递增子序列int[] dp = new int[n];dp[0] = 1;int maxn = 1;for (int j = 1; j < n; ++j) {dp[j] = 1;for (int k = 0; k < j; ++k) {if (y[j] > y[k]) dp[j] = Math.max(dp[j], dp[k] + 1);}maxn = Math.max(maxn, dp[j]);}System.out.println(maxn);}}
}

在这里插入图片描述

binarySearch + 贪心(AC)

import java.util.*;public class Main {static class Node {public int x;public int y;public Node() {}}public static void main(String[] args) {Scanner sc = new Scanner(System.in);int T = sc.nextInt();int n;for (int i = 0; i < T; ++i) {n = sc.nextInt();Node[] x = new Node[n];// 存储 x - yfor (int j = 0; j < n; ++j) {Node node = new Node();node.x = sc.nextInt();x[j] = node;}for (int j = 0; j < n; ++j) {x[j].y = sc.nextInt();}// 排序Arrays.sort(x, (Node a, Node b) -> {if (a.x != b.x) return a.x - b.x;else return - (a.y - b.y);});int[] y = new int[n];for (int j = 0; j < n; ++j) {y[j] = x[j].y;}// 求最长递增子序列int len = 1;int[] d = new int[n + 1];d[len] = y[0];for (int j = 1; j < n; ++j) {// y[j] 大于d当前最末尾元素if (y[j] > d[len]) {d[++len] = y[j];}else {int lef = 1, rig = len, ans = 0;while (lef <= rig) {int mid = (lef + rig) >> 1;if (d[mid] < y[j]) {ans = mid;lef = mid + 1;}else {rig = mid - 1;}}d[ans + 1] = y[j];}}System.out.println(len);}}
}

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python面向对象 | 继承、多态、封装

欢迎关注博主 Mindtechnist 或加入【智能科技社区】一起学习和分享Linux、C、C、Python、Matlab&#xff0c;机器人运动控制、多机器人协作&#xff0c;智能优化算法&#xff0c;滤波估计、多传感器信息融合&#xff0c;机器学习&#xff0c;人工智能等相关领域的知识和技术。关…

全面:vue.config.js 的完整配置

vue.config.js是Vue项目的配置文件&#xff0c;用于配置项目的构建、打包和开发环境等。 在Vue CLI 3.0之后&#xff0c;项目的配置文件从原来的build和config目录下的多个配置文件&#xff0c;合并成了一个vue.config.js文件。这个文件可以放在项目的根目录下&#xff0c;用于…

IT部门都想要的跨网文件交换解决方案,了解一下

近年来全球网络安全威胁态势的加速严峻&#xff0c;使得企业对于网络安全有了前所未有的关注高度&#xff0c;企业的网络安全体系建设正从“以合规为导向”转变到“以风险为导向”&#xff0c;从原来的“保护安全边界”转换到“保护核心数据资产”的思路上来。 为了保护企业的核…

第十三届蓝桥杯物联网试题(省赛)

做后感悟&#xff1a; OLED显示函数需要一直显示&#xff0c;所以在主函数中要一直循环&#xff0c;为了确保这个检错功能error只输出一次&#xff0c;最好用中断串口进行接收数据&#xff0c;数据收完后自动进入中断函数中&#xff0c;做一次数据检查就好了&#xff0c;该开灯…

干货分享DS5L1伺服电机通过倍讯科技485转 Profinet 网关与西门子PLC进行通信的配置方法

倍讯科技485转 ProfinetDS5L1 伺服电机与 Profinet 网关进行通信需要了解 Profinet 协议和伺服电机的具体通信要求。以下是您可以如何解决此问题的总体概述&#xff1a; 了解 Profinet&#xff1a;Profinet 是自动化工业以太网标准。您需要了解 Profinet 的工作原理、其寻址方案…

【数据结构与算法】直接插入排序和希尔排序

引言 进入了初阶数据结构的一个新的主题——排序。所谓排序&#xff0c;就是一串记录&#xff0c;按照其中的某几个或某些关键字的大小&#xff08;一定的规则&#xff09;&#xff0c;递增或递减排列起来的操作。 排序的稳定性&#xff1a;在一定的规则下&#xff0c;两个值…

文件的介绍

文件介绍 文件是计算机中用于存储数据的一种载体。一般储存在磁盘上。 文件通常以一定的格式和结构存储数据&#xff0c;可以包含文本、图像、音频、视频等各种类型的信息。 文件可以通过文件系统进行管理和组织&#xff0c;用户可以对文件进行创建、打开、编辑、保存、复制…

PC电脑技巧[笔记本通过网线访问设备CMW500]

笔记本局域网访问设备 现在我有一台CMW500,我要用笔记本去访问它,但是我发现没有路由器就是不能够访问,通过网线连接设备就是ping不通: 这里设置TCP/IPv4的IP地址如下,这时候就可以pin通了:

利用RWKV-Runner初步感受一下ai的世界

最近又听到群里的高手在讨论RWKV-Runner&#xff0c;于是没忍住&#xff0c;就想试试&#xff0c;没想到第一关就卡住了。 从群里大咖上传的RWKV-Runner_windows_x64.exe文件开始吧&#xff0c;又找了个虚拟机&#xff0c;直接放在桌面上运行一下&#xff0c;结果就跳出一堆文…

WMS仓储管理系统如何优化供应链管理

随着信息技术的快速发展和市场竞争的加剧&#xff0c;优化供应链管理已成为企业提升竞争力的关键。WMS仓储管理系统作为供应链管理的核心工具&#xff0c;其在优化供应链过程中的作用日益凸显。本文将深入探讨WMS仓储管理系统如何优化供应链管理。 首先&#xff0c;WMS仓储管理…

有趣的css - 乱转的指北针

大家好&#xff0c;我是 Just&#xff0c;这里是「设计师工作日常」&#xff0c;今天分享的是使用 css 模拟实现搜索图标过渡到输入框的小动效的一个效果。 《有趣的css》系列最新实例通过公众号「设计师工作日常」发布。 目录 整体效果核心代码html 代码css 部分代码 完整代码…

MySQL进阶-----索引的结构与分类

目录 前言 一、认识索引 二、索引结构 1.概述 2. 二叉树 3 .B-Tree 4.BTree 5.Hash 三、索引的分类 1 .索引分类 2 .聚集索引&二级索引 前言 索引&#xff08;index&#xff09;是帮助MySQL高效获取数据的数据结构(有序)。在数据之外&#xff0c;数据库系统还维…