算法设计与分析第二章作业

C++解决最大子段和问题 给定由n个整数可能为负整数组成序列a[1],a[2],a[3],…,a[n],**最大子段和问题**(sum of largest sub-segment problem)要序列如a[i]+a[i+1]++a[j]的最大值,当所给的整数均为负数时定义子段和为0,依此定义,所的最优值为:Max{0,a[i]+a[i+1]++a[j]},1<=i<=j<=n。例如,当(a[1],a[2],a[3],a[4],a[5],a[6])=(-20,11,-4,13,-5,-2)时,最大子段和为20。 阅读详情

算法设计与分析第二章作业

题目描述

给定n个整数(可能为负数)组成的序列a[1],a[2],a[3],…,a[n],求该序列如a[i]+a[i+1]+…+a[j]的子段和的最大值。当所给的整数均为负数时,定义子段和为0。(要求算法的时间复杂度为O(n)。)

输入格式:输入有两行:第一行是n值(1<=n<=10000);第二行是n个整数。
输出样式:输出最大子段和。

输入样例:
6
-2 11 -4 13 -5 -2

输出样例:
20

**思路:**若n=1(即序列中只有1个元素),若该元素大于0,则返回该元素;否则返回0(定义一个序列的最大连续子段和至少为0,若元素全为负数,定义其和为0);

  1. 该子序列完全落在左半部,即a[0…mid]中,采用递归求最大连续子段和maxLeftSum;
  2. 该子序列完全落在右半部,即a[mid+1…n-1]中,采用递归求最大连续子段和maxRightSum;
  3. 该子序列跨越a的中部而占据左右部分,以中间元素amid为界,向左边部分和右边部分扩张,以左边为例,定义leftBorderSum=0,maxLeftBorderSum=0
  4. 让leftBorderSum从中间让左边累加,如果遇到正数就把正数加上去,并把结果赋值给maxleftBorderSum (表现形式就是如果leftBorderSum > maxLeftBorderSum说明加了个正数);
  5. 右边同样的道理。最后 maxMidSum = maxleftBorderSum + maxRightBorderSum
  6. 比较出1,2,3,中所求的数那一个最大即为所求结果。

关键: 以数组中点为界,目标值只能在三处—要么在中点左边(不含中点),要么必须包含中点,要么右边(不含中点)。

伪代码:

int maxSubSum(int *a, int left, int right) {
	if (left == right) {
		return a[left] < 0 ? 0 : a[left];
	}
	    int centor = (left + right) / 2;
    int leftSum = maxSubSum(a, left, centor);
    int rightSum = maxSubSum(a, centor + 1, right);
    int s1 = 0;
    int lefts =0;
    for (int i = centor; i >= left; i--) { // 从中点向左找最大字段和
        lefts += a[i];
        if (lefts > s1) {
            s1 = lefts;
        }
    }
    int s2 = 0;
    int rights = 0;
    for (int i = centor + 1; i <= right; i++) {//从中点向右找最大字段和
        rights += a[i];
        if (rights > s1) {
            s1 = rights;
        }
    }
    int sum = s0 + s1; // 第三种情况的最大子段和
    sum = max(sum, leftSum); // 求解三种情况的最大值
    sum = max(sum, rightSum);
    return sum;
}
int maxSum(int *a, int n) {
	return sumSubSum(a, 1, n); // 可以根据数组a自行调整
}


时间复杂度O(logN)

空间复杂度O(logN)–来源递归调用栈产生的空间

心得体会

分治法概念上理解就是将整个问题分解成若干小问题后再分而治之。如果分解得到的子问题相对来说还是太大,则可反复使用分治策略将这些子问题分成更小的同类型子问题,直至产生方便求解的子问题,必要时逐步合并这些子问题的解,从而得到问题的解,类似一个递归过程。分治法是一种设计算法的思想,大大优化了算法的运行时间复杂度,优化了程序,如何熟练使用需要继续进行不断地练习才能感悟。

线性DP做题整合 1065 最小正子段和基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3算法题 收藏 关注N个整数组成序列a[1],a[2],a[3],…,a[n],从中选出一个子序列(a[i],a[i+1],…a[j]),使这个子序列的和&gt;0,并且这个和是所有和&gt;0的子序列中最小的。例如:4,-1,5,-2,-12,6,-2。-1,5,-2,-1序列和为1,是最小的。... 阅读详情

相关推荐

基于Simulink的自适应控制(Adaptive Control)电励磁同步电动机

目录基于Simulink的自适应控制(Adaptive Control)电励磁同步电动机项目实例1. 项目背景2. 系统架构2.1 电励磁同步电动机模型2.2 三相逆变器模型2.3 自适应控制器(Adaptive Controller)2.4 系统框图3. 模型设计3.1 创建Simulink模型3.2 自适应控制(Adaptive Control)设计3.3 仿真环境搭建4. 参数优化4.1 自动调优5. 实际应用案例5.1 工业驱动系统5.2 风力发电系统6. 结论进一步优化建议需分析电励磁同步电动机

MHD0815的博客 237

MAX SUM 给定由n整数(可能负数)组成序列 {a1,a2,…,an},序列形如ai+ai+1,…,+aj的子段和的最大值。当所有的整数均为负数时定义其最大子段和为0。

Description 给定由n整数(可能负数)组成序列 {a1,a2,…,an},序列形如ai+ai+1,…,+aj的子段和的最大值。当所有的整数均为负数时定义其最大子段和为0。 Input 输入包含多组测试数据。第一行为一个整数C,表示有C组测试数据,接下来有2*C行数据,每组测试数据占2行,每组测试数据第一行是1整数n,表示有n个整数,接下来一行有n个整数,它们之间用空格隔开. Output 你的输出应该有C行,即每组测试数据的输出占一行,它是计算出的最大子段和. Sample Input 1 6 -2 11 -4 13 -5 -2 Sample Output 20

【绝对要收藏-优秀论文范文】高项-度量绩效域

摘要:本文基于某水库数字孪生平台建设项目(2022.9-2023.5,645.97万元)的管理实践,从信息系统度量绩效域角度展开论述。项目构建了包含防洪调度等6大子系统的数字平台,实现洪水"四预"功能。重点分析了度量绩效域的五大要点:制定有效指标(如成本±8%偏差阈值)、多维数据采集、预警临界值设定、基于趋势的主动干预和持续改进机制。特别阐述了绩效问题的诊断方法,包括设备采购全周期成本分析、阶段性成本报告制度等。项目状态展示采用三维可视化看板,集成进度、成本、质量等多维度实时数据,最终实

xylllamm的博客 334

最大子段和

问题描述:给定n个整数可能负数组成序列a[1],a[2],a[3],…,a[n],序列如a[i]+a[i+1]++a[j]的子段和的最大值。

Comsmelo的博客 1067

最大子段和问题

题目 Problem Description 给定n(1<=n<=100000)整数可能负数组成序列a[1],a[2],a[3],…,a[n],序列如a[i]+a[i+1]++a[j]的子段和的最大值。当所给的整数均为负数时定义子段和为0,依此定义,所的最优值为: Max{0,a[i]+a[i+1]++a[j]},1<=i<=j<=n。 例如...

茶小⑦的学习日常 532

算法设计分析第二章作业2020011043

学号:2020011043

qq_52111395的博客 201

算法设计分析第二章课后作业

算法设计分析第二章课后作业

public000001的博客 3317

算法设计分析 第二章博客作业

设计一个平均时间为O(n)算法,在n(1<=n<=1000)个无序的整数中找出第k小的数。提示:函数int partition(int a[],int left,int right)的功能是根据a[left]~a[right]中的某个元素x(如a[left])对a[left]~a[right]进行划分,划分后的x所在位置的左段全小于等于x,右段全大于等于x,同时利用x所在的位置还可以计算出x是这批数据按升非降序排列的第几个数。

2302_80893113的博客 848

机器人控制系统的设计MATLAB仿真pdf及程序

机器人控制系统的设计MATLAB仿真+各章节对应的MATLAB程序,很全面。

上一篇: java 规范
下一篇: 算法设计与分析第三章作业
万事.
博客等级 码龄5年 61粉丝 13原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值