AcWing 1.2.1 最长上升子序列模型 + 动态规划 + 图解(详细)

(1)acwing 4557. 最长上升子序列 4557. 最长上升子序列 - AcWing题库

给定一个长度为 N 的整数序列 a1,a2,…,aN。请你计算该序列的最长上升子序列的长度。上升子序列是指数值严格单调递增的子序列

输入格式
  • 第一行包含整数 N
  • 第二行包含 N个整数 a1,a2,…,aN
输出格式
  • 一行,一个整数,表示最长上升子序列的长度
数据范围
  • 1≤N≤1000
  • 0≤ai≤100000
输入样例:
7
1 7 3 5 9 4 8
输出样例:
4

 C++代码:

#include <iostream>
#include <algorithm>
using namespace std;const int N = 1010;int n,res=0;
int arr[N],dp[N];int main() {scanf("%d",&n);for(int i=1;i<=n;i++) scanf("%d",&arr[i]);for(int i=1;i<=n;i++) {dp[i]=1;for(int j=1;j<i;j++) {if(arr[j]<arr[i]) dp[i] = max(dp[i],dp[j]+1);}if (res < dp[i]) res = dp[i]; // 取长的子序列}printf("%d\n",res);return 0;
}

也可以这样写:

int main() {scanf("%d",&n);for(int i=0;i<n;i++) scanf("%d",&arr[i]);dp[0]=1;for(int i=1;i<n;i++) {dp[i]=1;for(int j=0;j<i;j++) {if(arr[j]<arr[i]) dp[i] = max(dp[i],dp[j]+1);}if (res < dp[i]) res = dp[i]; // 取长的子序列}printf("%d\n",res);return 0;
}======================================================int main() {scanf("%d",&n);for(int i=1;i<=n;i++) scanf("%d",&arr[i]);dp[1]=1;for(int i=2;i<=n;i++) {dp[i]=1;for(int j=1;j<i;j++) {if(arr[j]<arr[i]) dp[i] = max(dp[i],dp[j]+1);}if (res < dp[i]) res = dp[i]; // 取长的子序列}printf("%d\n",res);return 0;
}

(2)acwing1017-怪盗基德的滑翔翼

假设城市中一共有 N幢 建筑排成一条线,每幢建筑的高度各不相同。初始时,怪盗基德可以在任何一幢建筑的顶端。他可以选择一个方向逃跑,但是不能中途改变方向(因为中森警部会在后面追击)。因为滑翔翼动力装置受损,他只能往下滑行(即:只能从较高的建筑滑翔到较低的建筑)。他希望尽可能多地经过不同建筑的顶部,这样可以减缓下降时的冲击力,减少受伤的可能性。请问,最多可以经过多少幢不同建筑的顶部(包含初始时的建筑)

输入格式

  • 输入数据第一行是一个整数K,代表有K组测试数据
  • 每组测试数据包含两行:第一行是一个整数N,代表有N幢建筑。第二行包含N个不同的整数,每一个对应一幢建筑的高度h,按照建筑的排列顺序给出

输出格式

  • 对于每一组测试数据,输出一行,包含一个整数,代表怪盗基德最多可以经过的建筑数量

数据范围

  • 1≤K≤100,
  • 1≤N≤100,
  • 0<h<10000

输入样例:

3
8
300 207 155 299 298 170 158 65
8
65 158 170 298 299 155 207 300
10
2 1 3 4 5 6 7 8 9 10

输出样例:

6
6
9

思路:移动方向一旦确定,就转换成了LIS问题,那么可以看作是两个方向的最长上升子序列问题,答案res为正向逆向LIS两个过程中的较大者

 C++代码:

// 当确定完方向和起点后,最长的距离是什么呢?
// 起点:a[i]
// 最长距离:以a[i]为结尾的最长上升子序列#include <iostream>
#include <algorithm>using namespace std;const int N = 110;int n;
int arr[N],dp[N];int main() {int T;scanf_s("%d", &T);while (T--) {scanf_s("%d", &n);for (int i = 1; i <= n; i++) scanf_s("%d", &arr[i]);// 正向求解LIS问题int res = 0;for (int i = 1; i <= n; i++) {dp[i] = 1;for (int j = 1; j < i; j++) {if (arr[i] > arr[j]) dp[i] = max(dp[i], dp[j] + 1);}res = max(res, dp[i]);}// 反向求解LIS问题for (int i = n; i>=1; i--) {dp[i] = 1;for (int j = n; j > i; j--) {if (arr[i] > arr[j]) dp[i] = max(dp[i], dp[j] + 1);}res = max(res, dp[i]);}printf("%d\n", res);}return 0;
}

(3)acwing1014-登山问题

五一到了,ACM队 组织大家去登山观光,队员们发现山上一共有N个景点,并且决定按照顺序来浏览这些景点,即每次所浏览景点的编号都要大于前一个浏览景点的编号。同时队员们还有另一个登山习惯,就是不连续浏览海拔相同的两个景点,并且一旦开始下山,就不再向上走了。队员们希望在满足上面条件的同时,尽可能多的浏览景点,你能帮他们找出最多可能浏览的景点数么?

输入格式

  • 第一行包含整数N,表示景点数量
  • 第二行包含N个整数,表示每个景点的海拔

输出格式

  • 输出一个整数,表示最多能浏览的景点数

数据范围

  • 2≤N≤1000

输入样例

8
186 186 150 200 160 130 197 220

输出样例

4

本题实质上是求正向反向两次LIS问题,两次的LIS过程相互独立,故所求为两端LIS过程中最长上升子序列的最大长度之和

  • res = max(res,f[i]+g[i]-1)

C++代码:

/*条件1:按照编号递增的顺序来浏览 => 必须是子序列条件2:相邻两个景点不能相同条件3:一旦开始下降,就不能上升了目标:求最多能浏览多少景点
*/#include <iostream>
#include <algorithm>using namespace std;
const int N = 1010;int n;
int arr[N];
int f[N], g[N];int main() {scanf_s("%d", &n);for (int i = 1; i <= n; i++) scanf_s("%d", &arr[i]);for (int i = 1; i <= n; i++) {f[i] = 1;for (int j = 1; j < i; j++) {if (arr[i] > arr[j]) f[i] = max(f[i], f[j] + 1);}}for (int i = n; i >= 1; i--) {g[i] = 1;for (int j = n; j > i; j--) {if (arr[i] > arr[j]) g[i] = max(g[i], g[j] + 1);}}int res = 0;for (int i = 1; i <= n; i++) res = max(res, f[i] + g[i] - 1);printf("%d\n", res);return 0;
}

(4)acwing 482.合唱队形 482. 合唱队形 - AcWing题库

N 位同学站成一排,音乐老师要请其中的 (N−K) 位同学出列,使得剩下的 K 位同学排成合唱队形。合唱队形是指这样的一种队形:设 K 位同学从左到右依次编号为 1,2…,K 他们的身高分别为 T1,T2,…,TK 则他们的身高满足 T1<…<Ti>Ti+1>…>TK(1≤i≤K)。你的任务是,已知所有 N 位同学的身高,计算最少需要几位同学出列,可以使得剩下的同学排成合唱队形。

输入格式
  • 输入的第一行是一个整数 N ,表示同学的总数
  • 第二行有 N 个整数,用空格分隔,第 i  个整数 Ti  是第 i 位同学的身高(厘米)
输出格式
  • 输出包括一行,这一行只包含一个整数,就是最少需要几位同学出列
数据范围
  • 2≤N≤100
  • 130≤T≤230

思路: 如果要使得出列的同学数量最少的话,就意味着要使剩下的数量最多。那意思就是要找到一个先上升再下降的序列,选个最大的。然后再用总数减去这个长度。

#include <iostream>
#include <algorithm>using namespace std;
const int N = 1010;int n;
int arr[N];
int f[N],g[N];int main() {scanf("%d", &n);for (int i = 1; i <= n; i++) scanf("%d", &arr[i]);for(int i=1;i<=n;i++) {f[i] = 1;for(int j=1;j<i;j++) {if(arr[i]>arr[j]) f[i] = max(f[i], f[j] + 1);}}for(int i=n;i>=1;i--) {g[i] = 1;for(int j=n;j>i;j--) {if(arr[i]>arr[j]) g[i] = max(g[i], g[j] + 1);}}int res=0;for(int i=1;i<=n;i++) res = max(res,f[i]+g[i]-1);printf("%d",n-res);return 0;
}

(5)acwing 1012.友好城市

输入样例: 

7
22 4
2 6
10 3
15 12
9 8
17 17
4 2

输出样例: 

4

 

>>思路和分析

对于任意一种合法的建立桥梁的方式,都可以对应一种因变量的上升子序列。反之,对于因变量的任何一个上升子序列,我们都可以唯一的对应一个合法的建桥方式。每一种建桥方式,建桥的数量和上升子序列的长度是相同的。因此左边集合(所有合法的建桥方式)的长度最大值就等于右边集合(上升子序列)的长度的最大值。
解法:先按照自变量的大小,把因变量排序。排好之后得到一个序列,然后在序列当中求最长的一个上升子序列。
排序思路:看一下什么会出现相交的情况?
本质:如果选出来的桥梁是没有交叉的,那么就意味着按照其中某一个点来排序,那么另外一个点对应的位置也一定要使有序的才可以。因为一旦出现逆序,就是有交叉的。没有交叉也就意味着一定没有逆序的。那本题其实就可以转化为求最长上升子序列的长度。 

C++代码: 

#include <iostream>
#include <algorithm>using namespace std;typedef pair<int, int> PII;const int N = 5010;int n;
PII q[N];
int f[N];int main() {scanf_s("%d", &n);for (int i = 0; i < n; i++) scanf_s("%d%d", &q[i].first, &q[i].second);sort(q, q + n);int res = 0;for (int i = 0; i < n; i++) {f[i] = 1;for (int j = 0; j < i; j++) {if (q[i].second > q[j].second) f[i] = max(f[i], f[j] + 1);}res = max(res, f[i]);}printf("%d\n",res);return 0;
}

(6)acwing 1016.最长上升子序列和

输入样例:  

7
1 7 3 5 9 4 8

 输出样例: 

18

 C++代码:

#include <iostream>
#include <algorithm>using namespace std;const int N = 1010;
int n;
int a[N], f[N];int main() {scanf_s("%d", &n);for (int i = 1; i <= n; i++) scanf_s("%d", &a[i]);for (int i = 1; i <= n; i++) {f[i] = a[i];for (int j = 1; j <i; j++) {if (a[i] > a[j]) f[i] = max(f[i], f[j] + a[i]);}}int res = 0;for (int i = 1; i <= n; i++) res = max(res, f[i]);printf("%d\n", res);return 0;
}

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

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

相关文章

UE4 使用材质后期 制作玻璃有雨效果

效果展示&#xff0c;其实这是一个动画效果 以上为所有逻辑 拿到TexCoord给到Panner&#xff0c;Time和Speed都是通过下面计算而来&#xff0c;后面讲&#xff0c;再拿到时间和速度值过后&#xff0c;加上扰动值&#xff0c;最后取G值&#xff0c;因为雨事从上而下的动&#xf…

MATLAB中polyvalm函数用法

目录 语法 说明 示例 特征多项式的矩阵计算 polyvalm函数的功能是矩阵多项式计算。 语法 Y polyvalm(p,X) 说明 Y polyvalm(p,X) 以矩阵方式返回多项式 p 的计算值。此计算方式等同于使用多项式 p 替换矩阵 X。 示例 特征多项式的矩阵计算 求解 4 阶帕斯卡矩阵的特征…

RZMO-A-030/210、HZMO-A-030/315电控比例压力阀控制器

RZMO-A-030/50、RZMO-A-030/210、RZMO-A-030/350、RZMO-A-030/100、RZMO-A-030/315、HZMO-A-030/50、HZMO-A-030/210、HZMO-A-030/350、HZMO-A-030/100、HZMO-A-030/315滑阀型先导式数字型比例溢流阀&#xff0c;用于压力开环控制&#xff0c;可提供板式或叠加式安装。A型&…

禁止chrome浏览器更新方式

1、禁用更新服务 WinR调出运行&#xff0c;输入services.msc&#xff0c;进入服务。 在服务中有两个带有Google Update字样&#xff0c;双击打开后禁用&#xff0c;并把恢复选项设置为无操作。 2、删除计划任务 运行taskschd.msc&#xff0c;打开计划任务程序库&#xff0c;在…

15套前端经典实战项目大合集,小白练手必备实战项目

15套前端经典实战项目大合集&#xff0c;悄悄练习&#xff0c;你会惊艳所有人。 今日我以内卷为荣&#xff0c;明日内卷以我为荣&#xff0c;不管学习哪门语言都要做出实际的东西来&#xff0c;这个实际的东西就是项目。 这里整理了15前端经典实战项目&#xff0c;每套都有完…

【蓝桥杯选拔赛真题01】C++参赛建议 青少年组蓝桥杯C++选拔赛真题 STEMA比赛真题解析

目录 C/C++参赛建议 一、题目要求 1、编程实现 2、输入输出 二、算法分析 <

EPPlus库的安装和使用 C# 中 Excel的导入和导出

安装 工具栏->NuGet 包管理器->管理解决方案的NuGet程序包 安装到当前项目中 使用 将 DataGridView 数据导出为Excel 首先&#xff0c;需要将数据DataGridView对象转换为DataTable private void btnExport_Click(object sender, EventArgs e) {// 1.将当前页面的data…

R语言入门看这一章就够了(上)

目录 一、R的基础 1.1、R的安装 1.2、牛刀小试 1.3、线性关系实例 1.4、工作空间 1.5、R包的使用 包的安装 结果的重用 二、R数据集 2.1、向量 2.2、矩阵 2.3、数组 2.4、数据框 2.5、列表 三、R的常用命令 四、list列表详解 五、数据源导入方法 5.1、键盘输…

Mysql进阶-索引篇(上)

目录 索引概述 索引结构 数据结构 二叉树 红黑树 B-Tree BTree Hash 索引分类 聚集索引&二级索引 聚集索引选取规则: 具体结构 索引基础语法 SQL性能分析 SQL执行频率 慢查询日志 profile详情 explain 索引概述 介绍&#xff1a; 索引&#xff08; index &…

JetBrains ReSharper Ultimate 2023.2.2

JetBrains ReSharper Ultimate 国外知名软件公司JetBrains专为软件开发软件编程人员制作的各类应用工具箱&#xff0c;如&#xff1b;PHP集成开发工具PHPStorm&#xff0c;Java整合开发工具IntelliJ IDEA&#xff0c;Python集成开发工具PyCharm&#xff0c;HTML/CSS/JS开发工具…

17 HAP 覆盖特性与链路损耗特性分析

HAP 覆盖特性与链路损耗特性分析 HAP平台高度&#xff1a;17~22km之间。HAP通信业务的覆盖区域取决于覆盖区边缘至平台的仰角&#xff0c;仰角越小&#xff0c;覆盖区域越大。覆盖区内不同地点的用户至平台的距离差别也越大。HAP和终端几何关系&#xff1a; B&#xff1a;地面…

Spring Boot 使用 Disruptor 做内部高性能消息队列

这里写自定义目录标题 一 、背景二 、Disruptor介绍三 、Disruptor 的核心概念3.1 Ring Buffer3.2 Sequence Disruptor3.3 Sequencer3.4 Sequence Barrier3.5 Wait Strategy3.6 Event3.7 EventProcessor3.8 EventHandler3.9 Producer 四、案例-demo五、总结 一 、背景 工作中遇…

手把手带你申请软著!助你提高通过率!!!

文章目录 背景证书图片注意事项杜绝雷同抄袭准备材料1、功能需求说明书2、项目源码3、身份证原件复印件4、软著的申请表格 申请软著准备及步骤撰写材料说明说样式源码文件样式&#xff1a; 提交材料审核材料下证 背景 之前也有开发一下小软件&#xff0c;但是没有意识到软著&a…

【杂记】Ubuntu20.04装系统,安装CUDA等

装20.04系统 安装系统的过程中&#xff0c;ROG的B660G主板&#xff0c;即使不关掉Secure boot也是可以的&#xff0c;不会影响正常安装&#xff0c;我这边出现问题的主要原因是使用了Ventoy制作的系统安装盘&#xff0c;导致每次一选择使用U盘的UEFI启动&#xff0c;就会跳回到…

【产品经理】APP备案(阿里云)

工信部《关于开展移动互联网应用程序备案工作的通知》 工业和信息化部印发了《关于开展移动互联网应用程序备案工作的通知》&#xff0c;“在中华人民共和国境内从事互联网信息服务的App主办者&#xff0c;应当依照相关法律法规等规定履行备案手续&#xff0c;未履行备案手续的…

PHP如何批量修改二维数组中值

每个name值加pex&#xff0c;age加5&#xff0c; 原数据&#xff1a; $data[["name">a,age>12],["name">b,age>22],["name">c,age>33],["name">d,age>44], ];实现效果 方案一、foreach引用方式 $data[["…

ubuntu 22.04 截图工具 shutter

sudo apt install shutter 快捷键F1 注意不支持wayland&#xff0c;登录时不要选择ubuntu wayland

景联文科技提供4D-BEV标注工具:提升自动驾驶感知能力的精准数据支持

4D-BEV标注是一种用于自动驾驶领域的数据标注方法。在3D空间的基础上&#xff0c;加入了时间维度&#xff0c;形成了四个维度。这种方法通过精准地跟踪和记录动态对象&#xff08;如车辆、行人&#xff09;的运动轨迹、姿势变化以及速度等信息&#xff0c;全面理解和分析动态对…

CTF-Crypto学习记录-第四天 “ “ --- SHA1安全散列算法,实现原理。

文章目录 前言SHA-1加密算法介绍关于SHA-1和MD5 SHA-1 加密过程原文处理设置初始值和数据结构定义加密运算原理过程 在python中调用SHA-1 前言 MD5学习MD5加密算法 SHA-1加密算法介绍 SHA-1&#xff08;Secure Hash Algorithm1&#xff0c;安全散列算法1&#xff09;是一种密…

02【Git分支的使用、Git回退、还原】

上一篇&#xff1a;01【Git的基本命令、底层命令、命令原理】 下一篇&#xff1a;03【Git的协同开发、TortoiseGit、IDEA的操作Git】 文章目录 02【Git分支的使用、Git回退、还原】一、分支1.1 分支概述1.1.1 Git分支简介1.1.2 Git分支原理 1.2 创建分支1.2.1 创建普通分支1.…