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

分治:最大子段和

题目:P1115 最大子段和 - 洛谷

计算左半边的最大子段和,计算右半边的最大子段和,计算中间的最大子段和,返回这三个中最大的。结束条件是 l >= r 时,返回数组所在的这个数。

提几个细节问题

分割区间:

        将区间分割为 [l, mid-1]和 [mid, r],这会导致区间重叠或间隙。例如,当 l和 r相邻时,mid-1可能小于 l,导致空区间或无效访问。

        正确的分割方式应该是将区间分为 [l, mid]和 [mid+1, r],确保区间连续且不重叠。

计算跨越中间的最大子段和​​:

        跨越中点的子段应该由 左半部分的 最大后缀 和 右半部分最大前缀和组成。

        从中点 mid向左扫描求最大后缀和(从大往左走)从中点 mid+1向右扫描求最大前缀和(从小往右),然后相加。

ret 应该作为局部区间

        ret不能作为全局,不然值容易被覆盖出现问题。

循环i的起始点

一个值计算总和,一个值计算最大。有suml, maxl 等于a[mid](往左走的起点),有sumr,maxr等于a[mid+1]。所以 循环i的起点 分别是mid-1 mid+2

#include <iostream>
using namespace std;const int N = 2e5 +10; int n;
int a[N];int dfs(int l, int r)
{if (l >= r) return a[l];int mid = (l+r)>>1;int ret = max(dfs(l, mid), dfs(mid+1, r));int suml = a[mid], sumr = a[mid+1];int maxl = suml, maxr = sumr;for (int i = mid-1; i >= l; i--){suml += a[i];maxl = max(maxl, suml);	}	 for (int i = mid+2; i <= r; i++){sumr += a[i];maxr = max(maxr, sumr);}return max(maxr + maxl, ret);
}int main()
{cin >> n;for (int i = 1; i <= n; i++) cin>> a[i];cout << dfs(1, n) << endl;return 0;}

  • 代码将数组分成两半,分别递归处理左半部分和右半部分,每次递归处理规模约为 n/2。

  • 在合并步骤中,有两个循环:一个从左半部分的中间向左遍历,另一个从右半部分的中间向右遍历。每个循环的时间与当前子数组的长度成正比,即 O(n)。

时间复杂度是n * logn

http://www.dtcms.com/a/482770.html

相关文章:

  • 从江网站建设松江企业网站建设
  • 贪心算法精选30道编程题 (附有图解和源码)
  • 五莲县财源建设网站为什么网站建设图片显示不出来
  • 第11周中间件漏洞
  • 【MySQL】从零开始了解数据库开发 --- 复合查询
  • 解决 Git 推送冲突:使用 Rebase 整合远程更改
  • synchronized锁升级过程详解
  • mit6s081 lab8 locks
  • 建站培训企业管理考研
  • MySQL中的数据类型占用空间和范围
  • Docker部署jenkins集成全自动打包部署
  • 台州自助建站公司做好的网站怎么发布
  • 重磅更新:Claude Code 现在支持插件啦
  • 23种设计模式——访问者模式 (Visitor Pattern)
  • 卧龙区微网站开发网络管理系统怎么打开
  • java用注解优雅校验入参
  • 平台网站建设收费制作网页素材图片
  • 基于OpenCV的实时疲劳检测系统实现
  • HTML5基础——4、表格
  • Docker 通信核心:docker.sock 完全指南
  • Flutter---Button
  • 网站建设需要敲代码吗信息流推广实施策划书
  • 广元网站建设电子商务网站建设主要内容
  • 4.4-中间件之gRPC
  • 网络与通信安全课程复习汇总1——课程导入
  • Qt模型控件:QTreeViewQTreeWidget
  • 河南省城乡建设厅官网廊坊快速优化排名
  • 网站建设应该考虑哪些问题企信宝
  • 青海做网站最好的公司互联网推广引流
  • 一天一个设计模式——装饰器模式