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

最长上升子序列的长度最短连续字段和(动态规划)

一.最长上升子序列长度

1.什么是最长上升子序列:

定义:子序列是从数组中删除部分元素(不改变顺序)得到的序列。不下降指序列中每个元素>=前一个元素。LIS即长度最长的不下降子序列。
示例:数组nums=[3,1,2,4,3]的LIS为[1,2,4]或[1,2,3],
长度=3。
应用价值:任务调度、股票买卖等。

2.动态规划原理:

核心思想:用动态规划记录以每个元素结尾的LIS长度。
状态定义:dp[i]表示以a[i]结尾的最长不下降子序列长度。
转移方程:dp[i] = max(dp[j]+1),其中j<i且a[j]≤a[i]。
初始条件:所有dp[i]=1(单个元素自成子序列)。
最终结果:max(dp[0...n-1])即为LIS长度。

3.数据示例:

        原数组a记录具体数据

31243
01234

                i=0:        nums[0]=3→无前驱元素,dp[0]=1
i=1:        nums[1]=1→j=0(3>1不满足)→dp[1]=1
i=2:        nums[2]=2→j=1(1<2→dp[1]+1=2)→dp[2]=2
i=3:        nums[3]=4→j=0,1,2(取j=2,dp[2]+1=3)→dp[3]=3
i=4:        nums[4]=3→j=0,1,2(取j=2,dp[2]+1=3)→dp[4]=3

        dp[i]记录到i位置,最长不下降子序列长度

11233
01234

4.程序实现:

初始化:将dp数组的所有元素初始化为1,因为每个元素自身都是一个长度为1的子序列。同时,max_len也初始化为1。
双重循环:外层循环遍历数组中的每个元素1(从1开始),内层循环遍历i之前的所有元素j,以检查是否可以构成更长的子序列。
条件判断:如果a[j]≤a[i],说明a[i]可以接在a[j]后面形成一个更长的不下降子序列。此时,更新dp[i]为dp[j]+1和当前dp[i]中的较大值。
实时更新:在每次内层循环结束后,将max_len更新为当前max_len和dp[i中的较大值。最终,max_len就是整个数组的LIS长度。

5.代码展示:

如下

方法一:

1.最长上升或者持平子序列

#include<iostream>
#include<iomanip>
#include<algorithm>
using namespace std;
//最长不下降子序列(上升或者持平)
int a[110];
int dp[110];
int n;
int main()
{cin>>n;for(int i = 1;i<=n;i++){cin>>a[i];}//1.初始化dp[1] = 1;for(int i = 2;i<=2;i++){dp[i] = 1;//最少可以连续1个不下降子序列for(int j = 1;j<i;j++){if(a[j]<=a[i]){dp[1] = max(dp[i],dp[j]+1);}}}cout<<dp[n];
}

2.最长上升子序列

#include<iostream>
#include<iomanip>
#include<algorithm>
using namespace std;
//最长不下降子序列(上升或者持平)
int a[110];
int dp[110];
int n;
int main()
{cin>>n;for(int i = 1;i<=n;i++){cin>>a[i];}//1.初始化dp[1] = 1;for(int i = 2;i<=2;i++){dp[i] = 1;//最少可以连续1个不下降子序列for(int j = 1;j<i;j++){if(a[j]<=a[i]){dp[1] = max(dp[i],dp[j]+1);}}}int ma = -1;for(int i = 1;i<=n;i++){ma = max(dp[1],ma);}cout<<ma;return 0;
}

方法二:

1.优化:

核心思想:贪心策略+二分查找,维护“最小末尾元素数组”tails。tails数组定义:tails[len]表示长度为len+1的LIS的最小末尾元素。

更新规则:遍历a[i],在tails中二分查找第一个>a[i]的位置pos:
-若pos = len:tails.push_back(nums[i]),len++
-否则:tails[pos]=a[i]
最终LIS长度:len

2.数据示例:

原数组a记录具体数据

31243
01234

        示例数组:a=[3,1,2,4,3],tails数组动态更新过程:
a[0]=3:        tails为空→tails=[3].len=1
a[1]=1:        二分查找pos=0→tails[0]=1,tails=[1]
a[2]=2:        二分查找pos=1→tails.push_back(2).tails=[1,2]
a[3]=4:        二分查找pos=2→tails.push_back(4).tails=[1,2,4]
a[4]=3:        二分查找pos=2→tails[2]=3.tails=[1.2.3]
最终LIS长度:len=3

        数组tail记录不同长度子序列的最小末尾元素

123
01234

3.程序实现:

二分查找:使用lower_bound函数在tails数组中查找第一个大于等于当前元素x的位置pqs
添加/替换:如果pos等于tails的长度,说明x是目前最大的元素,将其添加到tails末尾;否则,将tails[pos]替换为×,以维护“最小末尾元素”的性质。
返回结果:遍历完成后,tails数组的长度即为最长不下降子序列的长度。

4.代码展示:

如下

1.最长上升子序列

#include<iostream>
#include<iomanip>
#include<algorithm>
using namespace std;
//最长不下降子序列(上升或者持平)
int a[110];
int dp[110];
int n;
int ldp = 0;
int main()
{cin>>n;for(int i = 1;i<=n;i++){cin>>a[i];}for(int i = 1;i<=n;i++){bool flag = true;for(int j = 1;j<=ldp;j++){if(a[i]<=dp[j]){dp[j] = a[i];flag = false;break;}}if(flag == true) dp[++ldp] = a[i];}cout<<ldp;return 0;
}

二.最短连续字段和

1.问题定义:给定整数数组(可含负数),求连续非空子数组的最大和;若全为负数,返回0
2.应用场景:数据趋势分析、算法优化、动态规划入门教学

3.示例:数组-2,11,-4,13,-5,-2的最大子段为11,-4,13,和为20。

4.代码展示:

如下

#include<iostream>
#include<iomanip>
#include<algorithm>
using namespace std;
int a[110];
int dp[110];
int main()
{int n;cin>>n;for(int i = 1;i<=n;i++){cin>>a[i];}int ma = -999999999;for(int i = 1;i<=n;i++){dp[i] = a[i];dp[i] = max(dp[i],dp[i-1] + a[i]);ma = max(dp[i],ma);}cout<<ma;return 0;
}


文章转载自:

http://wqKFqqsi.xxhwg.cn
http://mphc93N9.xxhwg.cn
http://2O1aAUHn.xxhwg.cn
http://La8jP9n3.xxhwg.cn
http://g6bSYDES.xxhwg.cn
http://jxljpjE2.xxhwg.cn
http://JbNdldYI.xxhwg.cn
http://kVvSS856.xxhwg.cn
http://W0HaQHPG.xxhwg.cn
http://79OwAPiK.xxhwg.cn
http://gP8bOksd.xxhwg.cn
http://8ccGAXvH.xxhwg.cn
http://aGdTuI9X.xxhwg.cn
http://3bDTf6GI.xxhwg.cn
http://UdYpcEYz.xxhwg.cn
http://hUFEJB5d.xxhwg.cn
http://xxA2UtIz.xxhwg.cn
http://EjuVo2sT.xxhwg.cn
http://YTc3Z4Oy.xxhwg.cn
http://4xza7W14.xxhwg.cn
http://XEBxYgnK.xxhwg.cn
http://ifMaqZyC.xxhwg.cn
http://oejGeiuX.xxhwg.cn
http://iS0iyL17.xxhwg.cn
http://M8vXMChA.xxhwg.cn
http://egJR9LXd.xxhwg.cn
http://EkyOrpFg.xxhwg.cn
http://JWWLuTfB.xxhwg.cn
http://JA6t8kSy.xxhwg.cn
http://7YWzhefu.xxhwg.cn
http://www.dtcms.com/a/374359.html

相关文章:

  • 2025年最新AI大模型原理和应用面试题
  • Docker 轻量级管理Portainer
  • Aider AI Coding 智能上下文管理深度分析
  • 【Vue3】02-Vue3工程目录分析
  • JavaSE 集合从入门到面试:全面解析与实战指南
  • 《AI大模型应知应会100篇》第70篇:大模型驱动的自动化工具开发(国产化实战版)
  • 电机控制(四)-级联PID控制器与参数整定(MATLABSimulink)
  • mybatis-plus 的更新操作(个人资料更新) —— 前后端传参空值处理
  • 技术方案之数据迁移方案
  • LeetCode热题 15.三数之和(双指针)
  • 我对 OTA 的理解随记,附GD32/STM32例程
  • 快速构建数据集-假数据(生成划分)
  • c++ 杂记
  • Effective Modern C++ 条款26:避免在通用引用上重载
  • Android14 init.rc中on boot阶段操作4
  • PYQT5界面类继承以及软件功能开发小记
  • 【机器学习】吴恩达机器学习笔记
  • UE5 性能优化(1) 模型合并,材质合并
  • Selenium4+Pytest自动化测试框架实战
  • 基于RK3568多网多串(6网+6串+2光)1U/2U机架式服务器在储能与电力的应用
  • 【Python】运动路线记录GPX文件的操作API函数,以及相关GUI界面(支持复制、拼接、数据生成、修改,SRT字幕生成等功能)
  • 西嘎嘎学习 - C++vector容器 - Day 7
  • 第三章:Python基本语法规则详解(二)
  • Next系统总结学习(一)
  • 备考系统分析师-专栏介绍和目录
  • 【rk3229/rk3228a android7.1 LPDDR EMMC EMCP 批量sdk】
  • Kali 自带工具 dirb:Web 路径扫描与 edusrc 挖掘利器
  • 【系统分析师】第2章-基础知识:数学与工程基础(核心总结)
  • 房屋安全鉴定机构评价
  • JAVA:io字符流FileReader和FileWriter基础