当前位置: 首页 > news >正文

【算法提高:动态规划】1.2 最长上升子序列模型(TODO:最长公共上升子序列)

文章目录

  • 题目列表
    • 1017. 怪盗基德的滑翔翼
    • 1014. 登山
    • 482. 合唱队形
    • 1012. 友好城市(⭐排序后 最长上升子序列模型)
    • 1016. 最大上升子序列和
    • 1010. 拦截导弹
      • 解法1——最长递减子序列 + 贪心
      • 解法2——最长递减子序列 + 最长递增子序列(⭐贪心结论)
    • 187. 导弹防御系统⭐⭐⭐⭐⭐(至少需要多少个 上升/下降 子序列)(dfs + 最少需要多少最长上升子序列)⭐⭐⭐⭐⭐
    • 272. 最长公共上升子序列⭐⭐⭐⭐⭐
      • 解法1——一起计算🚹TODO
      • 解法2——先求最长公共子序列,再求最长上升子序列长度🚹TODO
  • 相关链接

题目列表

1017. 怪盗基德的滑翔翼

https://www.acwing.com/problem/content/1019/
在这里插入图片描述
注意 基德 可以从任意地方开始选择向左或向右出发。
所以需要 dp 两次。

import java.io.BufferedInputStream;
import java.util.*;public class Main {public static void main(String[] args) {Scanner sin = new Scanner(new BufferedInputStream(System.in));int k = sin.nextInt();while (k-- != 0) {int n = sin.nextInt(), ans = 1;int[] a = new int[n], dp = new int[n];Arrays.fill(dp, 1);for (int i = 0; i < n; ++i) {a[i] = sin.nextInt();for (int j = 0; j < i; ++j) {if (a[i] < a[j]) dp[i] = Math.max(dp[i], dp[j] + 1);}ans = Math.max(ans, dp[i]);}Arrays.fill(dp, 1);for (int i = n - 1; i >= 0; --i) {for (int j = n - 1; j > i; --j) {if (a[i] < a[j]) dp[i] = Math.max(dp[i], dp[j] + 1);}ans = Math.max(ans, dp[i]);}System.out.println(ans);}}
}

1014. 登山

https://www.acwing.com/problem/content/1016/
在这里插入图片描述
因为一旦开始向下走之后就不会再往上走了。

所以向上走的状态只能从向上走的状态转移过来;向下走的状态既能从向上走的状态转移过来,也可以从向下走的状态转移过来。

import java.io.BufferedInputStream;
import java.util.*;public class Main {public static void main(String[] args) {Scanner sin = new Scanner(new BufferedInputStream(System.in));int n = sin.nextInt();int[] a = new int[n];for (int i = 0; i < n; ++i) a[i] = sin.nextInt();int[][] dp = new int[n][2];int ans = 1;for (int i = 0; i< n; ++i) {dp[i][0] = dp[i][1] = 1;for (int j = 0; j < i; ++j) {if (a[i] > a[j]) {dp[i][0] = Math.max(dp[i][0], dp[j][0] + 1);}else if (a[i] < a[j]) {dp[i][1] = Math.max(dp[i][1], Math.max(dp[j][0], dp[j][1]) + 1);}}ans = Math.max(ans, Math.max(dp[i][0], dp[i][1]));}System.out.println(ans);}
}

482. 合唱队形

https://www.acwing.com/problem/content/484/
在这里插入图片描述
计算每个节点作为结尾位置时向左和向右的递减子序列的最长长度即可。

注意最后要求的答案是需要几位同学出列 而不是 最多保留几位同学。

import java.io.BufferedInputStream;
import java.util.*;public class Main {public static void main(String[] args) {Scanner sin = new Scanner(new BufferedInputStream(System.in));int n = sin.nextInt();int[] t = new int[n];for (int i = 0; i < n; ++i) t[i] = sin.nextInt();int[][] dp = new int[n][2];for (int i = 0; i < n; ++i) {dp[i][0] = dp[i][1] = 1;for (int j = 0; j < i; ++j) {if (t[i] > t[j]) dp[i][0] = Math.max(dp[i][0], dp[j][0] + 1);}}int ans = 1;for (int i = n - 1; i >= 0; --i) {for (int j = n - 1; j > i; --j) {if (t[i] > t[j]) dp[i][1] = Math.max(dp[i][1], dp[j][1] + 1);}ans = Math.max(ans, dp[i][0] + dp[i][1] - 1);}System.out.println(n - ans);}
}

1012. 友好城市(⭐排序后 最长上升子序列模型)

https://www.acwing.com/problem/content/1014/

在这里插入图片描述

按照一岸排序,求另一岸此时的最长递增子序列。

import java.io.BufferedInputStream;
import java.util.*;public class Main {public static void main(String[] args) {Scanner sin = new Scanner(new BufferedInputStream(System.in));int n = sin.nextInt();int[][] a = new int[n][2];for (int i = 0; i < n; ++i) {a[i][0] = sin.nextInt();a[i][1] = sin.nextInt();}// 按照一岸排序Arrays.sort(a, (x, y) -> x[0] - y[0]);// 求另一岸此时的最长递增子序列int ans = 0;int[] dp = new int[n];Arrays.fill(dp, 1);for (int i = 0; i < n; ++i) {for (int j = 0; j < i; ++j) {if (a[i][1] > a[j][1]) dp[i] = Math.max(dp[i], dp[j] + 1);}ans = Math.max(ans, dp[i]);}System.out.println(ans);}
}

1016. 最大上升子序列和

https://www.acwing.com/problem/content/1018/

在这里插入图片描述

跟最长上升子序列长度的方法差不多,只修改了递推公式部分,将 + 1 修改成了 + a[i]。

import java.io.BufferedInputStream;
import java.util.*;public class Main {public static void main(String[] args) {Scanner sin = new Scanner(new BufferedInputStream(System.in));int n = sin.nextInt();int[] a = new int[n];for (int i = 0; i < n; ++i) a[i] = sin.nextInt();int[] dp = new int[n];Arrays.setAll(dp, i -> a[i]);int ans = 0;for (int i = 0; i < n; ++i) {for (int j = 0; j < i; ++j) {if (a[i] > a[j]) {dp[i] = Math.max(dp[i], dp[j] + a[i]);}}ans = Math.max(ans, dp[i]);}System.out.println(ans);}
}

1010. 拦截导弹

https://www.acwing.com/problem/content/1012/

在这里插入图片描述
使用最长上升子序列模型解决问题1。(对于这题是个最长递减子序列)。

对于问题2,当一个新的导弹来临时,我们首先检查是否有已经存在的系统可以拦截它。如果可以,我们应该选择一个能够拦截这个新来的导弹并且当前最高高度最低的系统来拦截它
结论:从上面的贪心可以推出来,是在求最长上升子序列。

解法1——最长递减子序列 + 贪心

import java.io.BufferedInputStream;
import java.util.*;public class Main {public static void main(String[] args) {Scanner sin = new Scanner(new BufferedInputStream(System.in));final int N = 1001;int[] a = new int[N], dp = new int[N];int n = 0;while (sin.hasNext()) {a[n++] = sin.nextInt();}// 使用动态规划求解最多能拦截的导弹数int ans1 = 0;Arrays.fill(dp, 1);for (int i = 0; i < n; ++i) {for (int j = 0; j < i; ++j) {if (a[i] <= a[j]) {dp[i] = Math.max(dp[i], dp[j] + 1);}}ans1 = Math.max(ans1, dp[i]);}System.out.println(ans1);// 贪心List<Integer> ls = new ArrayList<>();for (int i = 0; i < n; ++i) {int k = 0;while (k < ls.size() && ls.get(k) < a[i]) k++;if (k >= ls.size()) ls.add(a[i]);else ls.set(k, a[i]);}System.out.println(ls.size());}
}

解法2——最长递减子序列 + 最长递增子序列(⭐贪心结论)

import java.io.BufferedInputStream;
import java.util.*;public class Main {public static void main(String[] args) {Scanner sin = new Scanner(new BufferedInputStream(System.in));final int N = 1001;int[] a = new int[N], dp = new int[N], dp2 = new int[N];int n = 0;while (sin.hasNext()) {a[n++] = sin.nextInt();}// 不递增和递增子序列的最大长度int ans1 = 0, ans2 = 0;Arrays.fill(dp, 1);Arrays.fill(dp2, 1);for (int i = 0; i < n; ++i) {for (int j = 0; j < i; ++j) {if (a[i] <= a[j]) {dp[i] = Math.max(dp[i], dp[j] + 1);} else dp2[i] = Math.max(dp2[i], dp2[j] + 1);}ans1 = Math.max(ans1, dp[i]);ans2 = Math.max(ans2, dp2[i]);}System.out.println(ans1 + "\n" + ans2);}
}

187. 导弹防御系统⭐⭐⭐⭐⭐(至少需要多少个 上升/下降 子序列)(dfs + 最少需要多少最长上升子序列)⭐⭐⭐⭐⭐

https://www.acwing.com/problem/content/189/

在这里插入图片描述
注意数据范围是 50 比较小。

在上一题的代码框架基础上 增加一个 dfs 爆搜。

import java.io.BufferedInputStream;
import java.util.*;public class Main {final static int N = 52;static int[] q = new int[N], up = new int[N], down = new int[N];static int ans = 0, n = 0;public static void main(String[] args) {Scanner sin = new Scanner(new BufferedInputStream(System.in));while (true) {n = sin.nextInt();if (n == 0) return;ans = 0;dfs(0, 0, 0);System.out.println(ans);}}// u,su,sd 表示枚举到了第一个数,当前上升子序列的个数,当前下降子序列的个数static void dfs(int u, int su, int sd) {if (su + sd >= ans) return;if (u == n) {ans = su + sd;return;}// 情况1:将当前数放到上升子序列中int k = 0;while (k < su && up[k] >= q[u]) k++;int t = up[k];up[k] = q[u];if (k < su) dfs(u + 1, su, sd);else dfs(u + 1, su + 1, sd);up[k] = t;      // 恢复现场// 情况2:将当签署放到下降子序列中k = 0;while (k < sd && down[k] <= q[u]) k++;t = down[k];down[k] = q[u];if (k < sd) dfs(u + 1, su, sd);else dfs(u + 1, su, sd + 1);down[k] = t;}
}

Q:为什么不用 bfs 来求解?
A:因为 bfs 需要的空间太大,可能会爆炸。(bfs 存一层,dfs 存一个路径)。

272. 最长公共上升子序列⭐⭐⭐⭐⭐

https://www.acwing.com/problem/content/274/

在这里插入图片描述

解法1——一起计算🚹TODO

dp[i][j] 表示 两个数组 0 ~ i 和 0 ~ j 之间的 且以 b[j] 为结尾的 最长公共上升子序列长度。

import java.io.BufferedInputStream;
import java.util.*;public class Main {public static void main(String[] args) {Scanner sin = new Scanner(new BufferedInputStream(System.in));int n = sin.nextInt();int[] a = new int[n], b = new int[n];for (int i = 0; i < n; ++i) a[i] = sin.nextInt();for (int i = 0; i < n; ++i) b[i] = sin.nextInt();// dp[i][j] 表示 两个数组 0 ~ i 和 0 ~ j 之间的最长公共上升子序列长度。int[][] dp = new int[n + 1][n + 1];for (int i = 1; i <= n; ++i) {int maxV = 1;      // 可以上升的长度for (int j = 1; j <= n; ++j) {dp[i][j] = dp[i - 1][j];if (a[i - 1] == b[j - 1]) dp[i][j] = Math.max(dp[i][j], maxV);  	// 相等,是公共子序列if (b[j - 1] < a[i - 1]) maxV = Math.max(maxV, dp[i - 1][j] + 1);	// 更新可以上升的长度}}int ans = Arrays.stream(dp[n]).max().getAsInt();System.out.println(ans);}
}

解法2——先求最长公共子序列,再求最长上升子序列长度🚹TODO

在这里插入代码片

相关链接

【算法】最长递增子序列:动态规划&贪心+二分查找

相关文章:

【算法提高:动态规划】1.2 最长上升子序列模型(TODO:最长公共上升子序列)

文章目录 题目列表1017. 怪盗基德的滑翔翼1014. 登山482. 合唱队形1012. 友好城市&#xff08;⭐排序后 最长上升子序列模型&#xff09;1016. 最大上升子序列和1010. 拦截导弹解法1——最长递减子序列 贪心解法2——最长递减子序列 最长递增子序列&#xff08;⭐贪心结论&am…...

会不会好奇ai绘画生成器?ai创作的灵感从何而来?

在这个宁静的公园里&#xff0c;阳光透过树叶的缝隙洒在的地面上&#xff0c;微风轻拂着艺术家的发丝&#xff0c;带来一丝清凉。坐在长椅上的他&#xff0c;手中紧握着一支触控画笔&#xff0c;目光凝视着眼前的美景。旁边一台智能绘画助手正在悄悄发光&#xff0c;它似乎能够…...

【Ajax】笔记-JQuery发送请求与通用方法

Get请求 语法格式&#xff1a; $.get(url, [data], [callback], [type]) url:请求的 URL 地址。data:请求携带的参数。callback:载入成功时回调函数。type:设置返回内容格式&#xff0c;xml, html, script, json, text, _default。 准备三个按钮分别测试Get 、Post、通用型方…...

视频的音频提取怎么做?这样提取很简单

提取视频中的音频通常在需要从视频中独立使用音频或需要对音频进行编辑时使用。例如&#xff0c;当我们需要将音频上传到音乐流媒体平台或将其用于播客或其他音频项目时&#xff0c;就可能需要从视频中提取音频。问题是该怎么提取呢&#xff1f;教给大家几种简单的提取方法&…...

几百本常用计算机开发语言电子书链接

GitHub - XiangLinPro/IT_book: 本项目收藏这些年来看过或者听过的一些不错的常用的上千本书籍&#xff0c;没准你想找的书就在这里呢&#xff0c;包含了互联网行业大多数书籍和面试经验题目等等。有人工智能系列&#xff08;常用深度学习框架TensorFlow、pytorch、keras。NLP、…...

Docker Compose 解析:定义和管理多容器应用,从多角度探索其优势和应用场景

&#x1f337;&#x1f341; 博主 libin9iOak带您 Go to New World.✨&#x1f341; &#x1f984; 个人主页——libin9iOak的博客&#x1f390; &#x1f433; 《面试题大全》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33…...

Linux系列---【CentOS 7通过MSTSC连接远程桌面】

安装对应的yum源 yum list lightdm xorgxrdp xrdp 可以看到这些软件都在epel中&#xff0c;如果没有的话&#xff0c;请先安装对应的yum源。命令如下&#xff1a; yum install -y epel-release 确认yum源没有问题之后&#xff0c;我们就可以进行安装了。 安装lightdm xorgxrdp…...

width: calc(~“100% - 267px“);动态css 调样式

.result-filtering {color: #8b8b8b;display: flex;// width: 82.6%;width: calc(~"100% - 267px");}...

Windows Server 2012 搭建网关服务器并端口转发

需求 使用 Windows server 作为Hyper-V 虚拟出许多虚拟机&#xff0c;基本上都分配了内网地址&#xff0c;现在需要这些虚拟机访问外网&#xff0c;或者外网直接访问这些虚拟机&#xff0c;必须配置一个网关服务器。我决定直接使用 Windows 的远程访问中的 NAT 服务来完成。 …...

基于linux下的高并发服务器开发(第三章)- 3.10 死锁

deadlock.c #include <stdio.h> #include <pthread.h> #include <unistd.h>// 全局变量&#xff0c;所有的线程都共享这一份资源。 int tickets 1000;// 创建一个互斥量 pthread_mutex_t mutex;void * sellticket(void * arg) {// 卖票while(1) {// 加锁pt…...

09.计算机网络——套接字编程

文章目录 网络字节序socket编程socket 常见APIsockaddr结构 UDP编程创建socket绑定socketsendto发送数据recvform接收数据关闭socket TCP编程创建socket绑定socketlisten监听套接字accept服务端接收连接套接字connect客户端连接套接字send发送数据recv接收数据关闭socket 工具n…...

Data Structure, Algorithm,and Applications in C++

在学习这本书进阶内容之前&#xff0c;我们可以跟着它的第一章部分再巩固和复习。本书由Sartaj Sahni撰写&#xff0c;由王立柱和刘志红翻译。全书通俗易懂&#xff0c;内容丰富&#xff0c;是巩固C内容的不二选择。希望本文对各位有所帮助。 目录 1.函数与参数 1.1.传值参数…...

Apipost使用教程

Apipost是一款集API调试、生成文档、Mock、测试于一体的协同工具。单个工具可以同时满足接口测试、生成/分享文档、Mock、流程测试等功能&#xff0c;还有超实用的多人多角色间实时协作的功能。将前端、后端、测试三种角色串联起来&#xff0c;从而实现工作流程无缝衔接、提高研…...

如何使用Python进行服务器管理和自动化操作?

使用Python进行服务器管理和自动化操作可以极大地简化和提高日常管理任务的效率。下面是一些常见的方法和工具&#xff1a; SSH库&#xff1a;使用Python的paramiko库可以通过SSH协议连接到服务器&#xff0c;执行命令、上传文件和下载文件等操作。 例如&#xff0c;使用para…...

Kafka-partition和消费者的关系

Kafka-partition 目录概述需求&#xff1a; 设计思路实现思路分析1.Kafka-partition2.消费者数量小于分区数量3. 拓展实现 参考资料和推荐阅读 Survive by day and develop by night. talk for import biz , show your perfect code,full busy&#xff0c;skip hardness,make a…...

使用克拉默法则进行三点定圆(二维)

目录 1.二维圆2.python代码3.计算结果 本文由CSDN点云侠原创&#xff0c;爬虫网站请自重。 1.二维圆 已知不共线的三个点&#xff0c;设其坐标为 ( x 1 , y 1 ) (x_1,y_1) (x1​,y1​)、 ( x 2 , y 2 ) (x_2,y_2) (x2​,y2​)、 ( x 3 , y 3 ) (x_3,y_3) (x3​,y3​)&#xf…...

【Java】Java多线程编程基础

文章目录 1. 进程与线程1.1 进程与线程的基本认识1.1.1 进程&#xff08;Process&#xff09;1.1.2 线程&#xff08;Thread&#xff09; 1.2 为什么会有线程1.2.1 以看视频为例 2. 多线程实现2.1 Thread类实现多线程2.2 Runnable接口实现多线程2.3 Callable接口实现多线程2.3 …...

FFmpeg-4.2.4的去logo源码分析

1.源码 libavfilter/vf_delogo.c 2.源码分析 /** 去logo算法, 函数的参数解释如下: w: 输入图像的宽度 h: 输入图像的高度 logo_x: 标志区域左上角的x坐标 logo_y: 标志区域左上角的y坐标 logo_w: 标志的宽度 logo_h: 标志的高度 band: 处理区域周围的带宽大小 show: 是否在…...

深度学习(一)

目录 一、特征工程的作用 二、深度学习的应用 三、得分函数 四、损失函数 五、前向传播 六、反向传播 一、特征工程的作用 数据特征决定了模型的上限预处理和特征提取是最核心的算法与参数选择决定了如何逼近这个上限 二、深度学习的应用 无人驾驶人脸识别分辨率重构 深…...

Stream API将对象中的某一字段取出转换为list或数组

List<DevicePartMaintain> devicePartMaintainList devicePartMaintainMapper.selectDevicePartMaintainByMitId(mitId);所有id转换为List 要使用Stream流获取devicePartMaintainList中所有的id&#xff0c;您可以使用stream()方法将列表转换为流&#xff0c;然后使用…...

贪心-摆动序列、不重叠字串数量

Ref 贪心B站搜索-折半搜索 分发饼干 class Solution { public:int findContentChildren(vector<int>& g, vector<int>& s) {sort(g.begin(),g.end());sort(s.begin(),s.end());int cnt0;for(int i0,j0;i<g.size()&&j<s.size();){if(s[j]&…...

OpenClaw+GLM-4.7-Flash低成本方案:自建模型替代SaaS API

OpenClawGLM-4.7-Flash低成本方案&#xff1a;自建模型替代SaaS API 1. 为什么选择自建模型替代商业API 去年夏天&#xff0c;当我第一次尝试用OpenClaw自动化处理公司周报时&#xff0c;被OpenAI的API账单吓了一跳——简单的文档整理和摘要生成&#xff0c;一个月竟然消耗了…...

ECG-Emotion Recognition(情绪识别)实战指南:WESAD与DREAMER数据集深度解析与应用

1. 情绪识别与ECG技术入门指南 第一次接触ECG情绪识别时&#xff0c;我和大多数人一样充满疑惑&#xff1a;心跳数据真能反映人的情绪&#xff1f;经过三个月的项目实践&#xff0c;我可以肯定地说&#xff0c;ECG信号就像情绪的"心电图"&#xff0c;愤怒时心跳加速、…...

突破透明动画性能瓶颈:VAP引擎实现移动端高效视觉体验

突破透明动画性能瓶颈&#xff1a;VAP引擎实现移动端高效视觉体验 【免费下载链接】vap VAP是企鹅电竞开发&#xff0c;用于播放特效动画的实现方案。具有高压缩率、硬件解码等优点。同时支持 iOS,Android,Web 平台。 项目地址: https://gitcode.com/gh_mirrors/va/vap …...

AI赋能Spring开发:借助快马平台快速集成Spring AI,打造智能应用

AI赋能Spring开发&#xff1a;借助快马平台快速集成Spring AI&#xff0c;打造智能应用 Spring生态庞大&#xff0c;新技术集成往往需要查阅大量文档。最近我在尝试将Spring AI集成到项目中&#xff0c;发现这个过程比想象中要复杂得多。好在发现了InsCode(快马)平台&#xff…...

彻底解决Windows 11系统稳定性问题:ExplorerPatcher核心技术解析与实战指南

彻底解决Windows 11系统稳定性问题&#xff1a;ExplorerPatcher核心技术解析与实战指南 【免费下载链接】ExplorerPatcher 提升Windows操作系统下的工作环境 项目地址: https://gitcode.com/GitHub_Trending/ex/ExplorerPatcher 当你的Windows 11系统频繁出现界面无响应…...

别再一条条Update了!MyBatis批量更新数据,用这个Case When写法性能翻倍

MyBatis批量更新性能优化实战&#xff1a;告别低效循环&#xff0c;拥抱CASE WHEN 每次看到代码里用循环一条条执行update语句&#xff0c;我的数据库性能监控图表就会剧烈波动——这简直是DBA的噩梦。上周排查一个后台任务卡死问题&#xff0c;发现同事在处理5万条数据更新时&…...

Ollama平台部署GLM-4.7-Flash:从零开始搭建本地大模型服务

Ollama平台部署GLM-4.7-Flash&#xff1a;从零开始搭建本地大模型服务 1. 为什么选择GLM-4.7-Flash&#xff1f; 在众多开源大模型中&#xff0c;GLM-4.7-Flash以其独特的定位脱颖而出。这个30B参数的MoE&#xff08;混合专家&#xff09;模型&#xff0c;在性能与效率之间取…...

nli-distilroberta-base代码实例:Python调用DistilRoBERTa实现Entailment识别

nli-distilroberta-base代码实例&#xff1a;Python调用DistilRoBERTa实现Entailment识别 1. 项目概述 自然语言推理(Natural Language Inference, NLI)是自然语言处理中的一项重要任务&#xff0c;用于判断两个句子之间的逻辑关系。nli-distilroberta-base是基于DistilRoBER…...

NXP S32K3xx之HSE密钥管理与安全服务实战

1. HSE密钥管理基础&#xff1a;从零开始理解安全引擎 第一次接触NXP S32K3xx的HSE模块时&#xff0c;我被各种密钥术语搞得晕头转向。经过几个实际项目的打磨&#xff0c;现在我可以负责任地告诉你&#xff1a;理解HSE密钥管理就像学习一门新语言&#xff0c;掌握基础词汇后就…...