acwing算法提高之动态规划--最长上升子序列模型(下)

目录

  • 1 基础知识
  • 2 模板
  • 3 工程化

1 基础知识

暂无。。。

2 模板

暂无。。。

3 工程化

题目1:拦截导弹。给你N个数,第(1)问求最长下降子序列,第(2)问求需要多少个下降序列才能把所有元素覆盖住?

解题思路:第(1)直接用最长上升子序列的模型即可。第(2)问,需要贪心做法。

贪心做法的关键步骤,有

  1. 遍历每一个元素x:
  2. 如果现有子序列结尾值均小于等于x,新开一个下降子序列,x作为第一个元素。否则,将x插入到最不浪费空间的那个子序列结尾处(即大于等于x的最小值)。
  3. 开了多少个下降子序列,就是最终答案。

通过发现可以得到,上述贪心做法,和最长上升子序列的 O ( n l o g n ) O(nlogn) O(nlogn)做法一致,虽然代表的含义是不一样的,但答案是一样的。

C++代码如下,

#include <iostream>
#include <vector>using namespace std;const int N = 1010;
int n;
int a[N];
int f[N];int main() {while (cin >> a[n]) n++;int ans1 = 0;for (int i = 0; i < n; ++i) {f[i] = 1;for (int j = 0; j < i; ++j) {if (a[j] >= a[i]) {//注意可以取等于号f[i] = max(f[i], f[j] + 1);}}ans1 = max(ans1, f[i]);}cout << ans1 << endl;//求需要多少个下降子序列才能够把所有元素覆盖住vector<int> vec;for (int i = 0; i < n; ++i) {//在vec中找到大于a[i],且值最小的元素的下标int idx = -1;for (int j = 0; j < vec.size(); ++j) {if (vec[j] >= a[i]) {//注意可以取等于号idx = j;break;}}if (idx == -1) {//说明没有找到,vec中的元素都比a[i]要小vec.emplace_back(a[i]);} else {//说明找到了vec[idx] = a[i];}}cout << vec.size() << endl;return 0;
}

可以将第(2)问求需要多少个下降子序列才能够把元素覆盖住,转换为求最长上升子序列。C++代码如下,

#include <iostream>
#include <vector>
#include <cstring>using namespace std;const int N = 1010;
int n;
int a[N];
int f[N];int main() {while (cin >> a[n]) n++;int ans1 = 0;for (int i = 0; i < n; ++i) {f[i] = 1;for (int j = 0; j < i; ++j) {if (a[j] >= a[i]) {//注意可以取等于号f[i] = max(f[i], f[j] + 1);}}ans1 = max(ans1, f[i]);}cout << ans1 << endl;//求需要多少个下降子序列才能够把所有元素覆盖住memset(f, 0, sizeof f);//转换成求最长上升子序列int ans2 = 0;for (int i = 0; i < n; ++i) {f[i] = 1;for (int j = 0; j < i; ++j) {if (a[j] < a[i]) {f[i] = max(f[i], f[j] + 1);}}ans2 = max(ans2, f[i]);}cout << ans2 << endl;return 0;
}

更进一步,可以将上述求最长上升子序列的做法的时间复杂度从 O ( n 2 ) O(n^2) O(n2)优化到 O ( n l o g n ) O(nlogn) O(nlogn)。C++代码如下,

#include <iostream>
#include <vector>
#include <cstring>using namespace std;const int N = 1010;
int n;
int a[N];
int f[N];int main() {while (cin >> a[n]) n++;int ans1 = 0;for (int i = 0; i < n; ++i) {f[i] = 1;for (int j = 0; j < i; ++j) {if (a[j] >= a[i]) {//注意可以取等于号f[i] = max(f[i], f[j] + 1);}}ans1 = max(ans1, f[i]);}cout << ans1 << endl;//求需要多少个下降子序列才能够把所有元素覆盖住vector<int> q; //q[i]表示长度为length(length = i + 1)的上升子序列的结尾元素的最小值为q[i]for (int i = 0; i < n; ++i) {//在q中找到大于等于a[i]的第一个元素int idx = lower_bound(q.begin(), q.end(), a[i]) - q.begin();if (idx == q.size()) {//说明没有找到,q中所有的元素都小于a[i]q.emplace_back(a[i]);} else {//说明找到了q[idx] = a[i]; }}int ans2 = q.size();cout << ans2 << endl;return 0;
}

题目2:导弹防御系统。

解题思路:dfs。

C++代码如下,

#include <iostream>using namespace std;const int N = 55;
int a[N];
int up[N];
int down[N];
int n;
int ans;void dfs(int u, int sup, int sdown) {if (sup + sdown >= ans) return;if (u == n) {ans = sup + sdown;return;}//(1)将a[u]归到上升子序列中int k = 0;while (k < sup && up[k] >= a[u]) k++;if (k < sup) {int t = up[k];up[k] = a[u];dfs(u + 1, sup, sdown);up[k] = t;} else {up[k] = a[u];dfs(u + 1, sup + 1, sdown);}//(2)将a[u]归到下降子序列中k = 0;while (k < sdown && down[k] <= a[u]) k++;if (k < sdown) {int t = down[k];down[k] = a[u];dfs(u + 1, sup, sdown);down[k] = t;} else {down[k] = a[u];dfs(u + 1, sup, sdown + 1);}return;
}int main() {while (cin >> n, n) {for (int i = 0; i < n; ++i) cin >> a[i];ans = n;dfs(0, 0, 0);cout << ans << endl;}return 0;
}

题目3

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

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

相关文章

Retrofit的转换器

一、前言 1.为什么要使用Retrofit转换器 在我们接受到服务器的响应后&#xff0c;目前无论是OkHttp还是Retrofit都只能接收到String字符串类型的数据&#xff0c;在实际开发中&#xff0c;我们经常需要对字符串进行解析将其转变为一个JavaBean对象&#xff0c;比如服务器响应…

Codeforces Round 913 (Div. 3)(A~G)

1、编程模拟 2、栈模拟 3、找规律&#xff1f;&#xff08;从终止状态思考&#xff09; 4、二分 5、找规律&#xff0c;数学题 6、贪心&#xff08;思维题&#xff09; 7、基环树 A - Rook 题意&#xff1a; 直接模拟 // Problem: A. Rook // Contest: Codeforces - C…

Kotlin Lambda使用

Kotlin Lambda使用 fun main() /*: Unit*/ {// Lambda会慢慢的难度升级// Kotlin Unit Java void// TODO 下面全部都是函数声明&#xff0c; 既然是函数声明&#xff0c;就不能调用// 函数的声明 用lambda去描述函数的声明val method1 : () -> Unitval method2 : (Int, In…

火焰图的基本认识与绘制方法

火焰图的认识与使用-目录 火焰图的基本认识火焰图有以下特征(on-cpu)火焰图能做什么火焰图类型On-CPU 火焰图和Off-CPU火焰图的使用场景火焰图分析技巧 如何绘制火焰图生成火焰图的流程1.生成火焰图的三个步骤 安装火焰图必备工具1.安装火焰图FlameGraph脚本2.安装火焰图数据采…

智能优化算法应用:基于人工水母算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于人工水母算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于人工水母算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.人工水母算法4.实验参数设定5.算法结果6.参考…

4 STM32MP1 Linux系统启动过程

1. ROM代码 这是ST官方写的代码&#xff0c;在STM32MP1出厂时就已经烧录进去&#xff0c;不能被修改。ROM代码是上电以后首先执行的程序&#xff0c;它的主要工作就是读取STM32MP1的BOOT引脚电平&#xff0c;然后根据电平来判断当前启动设备&#xff0c;最后从选定的启动设备里…

快速认识,后端王者语言:Java

Java作为最热门的开发语言之一&#xff0c;长居各类排行榜的前三。所以&#xff0c;就算你目前不是用Java开发&#xff0c;你应该了解Java语言的特点&#xff0c;能用来做什么&#xff0c;以备不时之需。 Java 是一种高级、多范式编程语言&#xff0c;以其编译为独立于平台的字…

快手数仓面试题附答案

题目 1 讲一下你门公司的大数据项目架构&#xff1f;2 你在工作中都负责哪一部分3 spark提交一个程序的整体执行流程4 spark常用算子列几个&#xff0c;6到8个吧5 transformation跟action算子的区别6 map和flatmap算子的区别7 自定义udf&#xff0c;udtf&#xff0c;udaf讲一下…

Java链接数据库

本文介绍的是Java链接数据库中的JDBC操作&#xff0c;JDBC虽然现在用的不多&#xff0c;但面试的时候会问道。需要有相应的了解。下面以链接MySQL为例子。 JDBC 什么jdbc Java DataBase Connectivity是一种用于执行SQL语句的Java API&#xff0c;它由一组用Java语言编写的类和…

初识Protobuf与Protobuf的安装

目录 一、Protobuf 1.回顾序列化 2.Protobuf的特性 3.Protobuf的下载 ①ProtoBuf 在 window 下的安装 ②ProtoBuf 在 Linux 下的安装 一、Protobuf 1.回顾序列化 我们在先前的学习中也遇到过序列化。所谓序列化我的理解是&#xff0c;将复杂的对象以特定的方式转换以便于…

【计算机网络笔记】物理层——信道与信道容量

系列文章目录 什么是计算机网络&#xff1f; 什么是网络协议&#xff1f; 计算机网络的结构 数据交换之电路交换 数据交换之报文交换和分组交换 分组交换 vs 电路交换 计算机网络性能&#xff08;1&#xff09;——速率、带宽、延迟 计算机网络性能&#xff08;2&#xff09;…

【稳定检索|投稿优惠】2024年光电信息与机器人发展国际会议(ICOIRD 2024)

2024年光电信息与机器人发展国际会议(ICOIRD 2024) 2024 International Conference on Optoelectronic Information and Robot Development(ICOIRD 2024) 一、【会议简介】 信息技术与人工智能的浪潮正在激荡&#xff0c;不断刷新我们生活的页面&#xff0c;深刻烙印在光电信息…

Homework 3: Higher-Order Functions, Self Reference, Recursion, Tree Recursion

Q1: Compose 编写一个高阶函数composer&#xff0c;它返回两个函数func和func_adder。 func是一个单参数函数&#xff0c;它应用到目前为止已经组合的所有函数。这些函数将首先应用最新的函数&#xff08;参见doctests和示例&#xff09;。 func_adder用于向我们的组合添加更多…

虚拟局域网(VLAN)解析(Virtual Local Area Network)(用于在不受物理位置限制的情况下将设备划分到同一网络或不同网络)

文章目录 虚拟局域网&#xff08;VLAN&#xff09;解析1. VLAN简介2. VLAN工作原理3. VLAN类型1. 静态VLAN2. 动态VLAN 4. VLAN优点提高安全性降低网络拥堵更简单的管理 5. 如何配置VLAN1. 进入全局配置模式2. 创建VLAN并命名3. 将端口分配给VLAN4. 验证VLAN配置 6. 常见问题与…

“快慢指针”思想在物理或者逻辑循环中的应用

1 基础概念 1.1 什么是物理循环和逻辑循环&#xff1f; 物理循环是指物理索引访问顺序上相邻&#xff0c;逻辑上也相邻&#xff0c;比如循环链表&#xff0c;逻辑循环则指物理的索引上不一定相邻 1.2 快慢指针本质上可以解决逻辑循环问题&#xff0c;而物理循环也属于逻辑循…

用AI在抖音直播做姓氏头像的全新玩法,详细分析制作教程

前段时间在圈子里给大家分享了用AI写艺术字做小红书账号案例玩法&#xff0c;同学们都比较热衷学习。纷纷动手实践。 事实上用AI艺术字变现玩法还有许多。 例如上周末在星球给圈友们分享的一个AI艺术字直播的抖音账号&#xff0c;直播内容形式很简单&#xff0c;就是展现用AI…

七大经典高效学习方法

金字塔学习模型 金字塔学习是美国学习专家爱德加戴尔1946年提出的。 他将学习分为主动学习和被动学习两种类型&#xff0c;用数字形象地呈现了采用不同学习方式&#xff0c;学习者在两周后还能记住的内容有多少。 被动学习&#xff1a;通过听讲、阅读、视听、演示这些活动&a…

Java网络编程——基础入门

1、进程间的通信 进程指运行中的程序&#xff0c;进程的任务就是执行程序中的代码。EchoPlayer类是一个独立的Java程序&#xff0c;它可以在任意一台安装了JDK的主机上运行&#xff1a; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStr…

Linux socket编程(11):Unix套接字编程及通信例子

Unix套接字是一种用于在同一台计算机上的进程间通信的一种机制。它是Linux和其他类Unix系统中的一项特性&#xff0c;通过在文件系统中创建特殊的套接字文件&#xff0c;进程可以通过这些套接字文件进行通信。 文章目录 1 Unix和TCP套接字对比2 Unix套接字初始化流程3 例:服务端…

3.4 路由器的DHCP配置

实验3.4 路由器的DHCP配置 一、任务描述二、任务分析三、具体要求四、实验拓扑五、任务实施&#xff08;一&#xff09;配置基于接口地址池的DHCP1.交换机的基本配置2.路由器的基本配置3.开启路由器的DHCP服务器功能4.配置路由器接口的DHCP功能5.设置计算机使用DHCP方式获取IP地…