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

最大m子段和

  • 问题描述
  • 解题思路
  • 伪代码
  • 代码实现
  • 复杂度分析

问题描述

给定一个有n(n>0)个整数的序列,要求其m个互不相交的子段,使得这m个子段和最大。
输入:整数序列{nums},m。
输出:最大m子段和。

对于m=1的情况,即求最大子数组和

解题思路

我们采用动态规划的思路解决这个问题:
根据常用的状态表示经验我们可以记dp[k][i]为前i个元素的最大k子段和,记last[k][i]为前i个元素中以nums[i-1]结尾的最大k子段和。

对于last[k][i]不难发现有两种情况:

  1. 若第k子段长度大于1,即last[k][i]=last[k][i-1]+nums[i-1];
  2. 若第k子段长度等于1,即last[k][i]=max{last[k-1]}+nums[i-1].则last[k][i]=max{last[k][i-1]+nums[i-1],max{last[k-1]}+nums[i-1]}.

容易得到dp[k][i]=max{dp[k],[i-1],last[k],[i]};
初始化last[1][1]=dp[1][1]=nums[0],last[1][i]=max{last[1][i-1]+nums[i-1],nums[i-1]},dp[1][i] = max(dp[1][i - 1], last[1][i]).

所求的最大m子段和即为dp[m][n].

伪代码

FUNCTION MaxSubArrayM(nums, m) :
Beginn ← LENGTH(nums)DECLARE last[1:n][1:m], dp[1:n][1:m]last[1][1] ← nums[0]dp[1][1] ← nums[0]FOR j FROM 2 TO n :last[1][j] ← MAX(nums[j - 1], last[1][j - 1] + nums[j - 1])dp[1][j] ← MAX(dp[1][j - 1], last[1][j])End For// 处理多子段FOR i FROM 2 TO m :dp[i][0] ← INT_MINlast[i][i - 1] ← INT_MINFOR j FROM i TO n :option1 ← last[i][j - 1] + nums[j - 1]  option2 ← dp[i - 1][j - 1] + nums[j - 1] last[i][j] ← MAX(option1, option2)dp[i][j] ← MAX(dp[i][j - 1], last[i][j])End ForEnd ForRETURN dp[m][n]
End MaxSubArrayM

代码实现

int MaxSubArrayM(vector<int>& nums,int m)
{vector<vector<int>>last(nums.size() + 1, vector<int>(m + 1)), dp(nums.size() + 1, vector<int>(m + 1));last[1][1] = dp[1][1] = nums[0];for (int i = 2; i <= nums.size(); i++){last[1][i] = max(nums[i - 1], nums[i - 1] + last[1][i - 1]);dp[1][i] = max(dp[1][i - 1], last[1][i]);}for (int i = 2; i <= m ; i++){dp[i][0] = last[i][i-1] = INT_MIN;for (int j = i; j <= nums.size(); j++){last[i][j] = max(last[i][j - 1] + nums[j - 1], dp[i - 1][j - 1] + nums[j - 1]);dp[i][j] = max(dp[i][j - 1], last[i][j]);}}return dp[m][nums.size()];
}

复杂度分析

时间复杂度:主要运行时间在两层for循环,故时间复杂度为O(mn).
空间复杂度:不难发现我们申请了m*n的两个vector,故空间复杂度为O(mn).

http://www.xdnf.cn/news/399853.html

相关文章:

  • WebGL图形编程实战【6】:性能优化 × 调试工具与技巧精讲
  • (done) 补充:xv6 的一个用户程序 init 是怎么启动的 ?它如何启动第一个 bash ?
  • 模块化PCB设计中联排半孔的应用
  • 接口出现 请求参数格式错误 的解决方法
  • 使用 Navicat 将 Excel 导入数据库
  • C#WPF里不能出现滚动条的原因
  • geoserver发布arcgis瓦片地图服务(最新版本)
  • web 自动化之 Unittest 应用:报告装饰器断言
  • spring中的@PropertySource注解详解
  • 【SSM-SSM整合】将Spring、SpringMVC、Mybatis三者进行整合;本文阐述了几个核心原理知识点,附带对应的源码以及描述解析
  • 《步进电机最小转速终极指南:从理论到实战,突破低速极限的5大秘技》
  • 未来技术展望:光子量子计算集成与连续变量可视化
  • 第二章、物理层
  • 基于CNN-BiLSTM-Attention的回归预测模型!
  • 基于注意力机制与iRMB模块的YOLOv11改进模型—高效轻量目标检测新范式
  • properties和yaml 文件加载指定配置文件的注解
  • MySQL 8.0 OCP 英文题库解析(三)
  • Java:编程世界的常青树与数字化转型的基石
  • VM中 ubuntu 网卡不显示
  • 机器学习第六讲:向量/矩阵 → 数据表格的数学表达,如Excel表格转数字阵列
  • HDFS客户端操作
  • 堆复习(C语言版)
  • 首屏优化,webpack插件用于给html中js自动添加异步加载属性
  • Linux操作系统从入门到实战(六)Linux开发工具(上)详细介绍什么是软件包管理器,Linux下如何进行软件和软件包的安装、升级与卸载
  • 探索边缘计算:赋能物联网的未来
  • 一.Gitee基本操作
  • 2025年阿里云ACP人工智能高级工程师认证模拟试题(附答案解析)
  • Vue:插值表达
  • 如何在 Bash 中使用 =~ 操作符 ?
  • 单词短语0512