选择特殊符号
选择搜索类型
请输入搜索
最大连续子数列和一道很经典的算法问题,给定一个数列,其中可能有正数也可能有负数,我们的任务是找出其中连续的一个子数列(不允许空序列),使它们的和尽可能大。我们一起用多种方式,逐步优化解决这个问题。
求出所有可能连续子列的和,时间复杂度O(N^3)
intMaxSubSequm1(intA[],intN){intThisSum,MaxSum=0;inti,j,k;for(i=0;iMaxSum) MaxSum=ThisSum; }} returnMaxSum; }
很显然上面的算法中,在计算子列和时,可以利用前一步计算和的结果,不需要每次从头累加。时间复杂度O(N^2) 。
intMaxSubSequm1(intA[],intN){ intThisSum,MaxSum=0; inti,j,k; for(i=0;iMaxSum) MaxSum=ThisSum; } } returnMaxSum; }
将问题一分为二,缩小问题规模,递归求解。
此处求解过程中要从中间基准点开始,扫描求出跨界的最大连续子列和,然后和左右边的解比较求出最终的结果。
时间复杂度O(N*logN)
我们可以通过抛弃负子列,保证最大子列和递增。当扫描一遍,最大子列和不再递增时,当前的最大子列和即为我们的解。这是最优算法,时间复杂度O(N)。
intMaxSubseqSum4(intA[],intN){ intThisSum,MaxSum; inti; ThisSum=MaxSum=0; for(i=0;iMaxSum) MaxSum=ThisSum; elseif(ThisSum<0) ThisSum=0; } returnMaxSum; }
Kadane算法扫描一次整个数列的所有数值,在每一个扫描点计算以该点数值为结束点的子数列的最大和(正数和)。该子数列由两部分组成:以前一个位置为结束点的最大子数列、该位置的数值。因为该算法用到了“最佳子结构”(以每个位置为终点的最大子数列都是基于其前一位置的最大子数列计算得出),该算法可看成动态规划的一个例子。
给定一个数列,例如【−2, 1, −3, 4, −1, 2, 1, −5, 4】, 求一个连续的数列使得数列内的元素和最大, 示例中最大子数列应该是【4, −1, 2, 1】, 求和值为6。
这个问题是可以衍生到一些变种问题, 如寻找数列中最大乘积序列,且要求序列中,相邻元素间隔不超过限定值等, 常出现在笔试面试编程题中。
该问题最早于1977年提出,但是直到1984年才被Jay Kadane 发现了线性时间的最优解法,所以算法虽然长度很短,但其实并不容易理解。
算法描述:
遍历该数组, 在遍历过程中, 将遍历到的元素依次累加起来, 当累加结果小于或等于0时, 从下一个元素开始,重新开始累加。
累加过程中, 要用一个变量(max_so_far)记录所获得过的最大值
一次遍历之后, 变量 max_so_far 中存储的即为最大子片段的和值。
此处为python 代码 , 变量A 传入数组。
首先, 题目中有一个隐含的设定, 最大子片段是可以为空的, 空片段的和值是0。 这一点必须要明确, 不然会无法理解算法的正确性, 所以当给定的数列中,求和为负数的时候,例如【-2,1, -3】, 算法会返回最大求和值0, 因为默认该数组的最大子片段是一个空序列。
理解此算法的关键在于:
算法可用如下Python代码实现:
defmax_subarray(A):max_ending_here=max_so_far=A[0]forxinA[1:]:max_ending_here=max(x,max_ending_here x)max_so_far=max(max_so_far,max_ending_here)returnmax_so_far
该问题的一个变种是:如果数列中含有负数元素,允许返回长度为零的子数列。该问题可用如下代码解决:
defmax_subarray(A):max_ending_here=max_so_far=0forxinA:max_ending_here=max(0,max_ending_here x)max_so_far=max(max_so_far,max_ending_here)returnmax_so_far
这种算法稍作修改就可以记录最大子数列的起始位置。Kadane算法时间复杂度为O(n),空间复杂度为O(1)。
图纸说明上:主要出口处门槛以斜面过渡,怎么理解这句话,实际施工是怎么操作的,应该怎么套定额?工程地点:河南省 问题补充: 斜面的斜度是多少?工程量怎么计算方便? 回复:这个是无障碍设计规范的要求,通常...
不知道您安装重新安装软件的时候有没有卸载掉原来的程序安装。目前可能是软件图标后缀名称有了改动引起的。也可能是病毒或者系统漏洞造成。 建议您重新安装下软件,安装之前,先卸载掉软件,然后到电脑里面找到之前...
估计还是差在主材价和基础上,你看看改用管道360度的基础看看能差多少钱
路面裂缝检测图像处理算法的研究
路面裂缝检测图像处理算法的研究——采用图像滤波和图像二值化方法,分析了几种图像处理算法,实现了针对路面裂缝图像的处理分析,获得了较好的图像处理效果,着重研究了均值滤波、中值滤波、维纳滤波、直方图阚值分割法、类间方差阈值分割法等几种滤波和二值化...
基于惯性测量单元的数字铁饼设计及数据处理算法研究
为了精确检测铁饼投掷的运动特征参数,设计了一种基于MEMS惯性测量单元和STM32F103微处理器的数字铁饼系统,阐述了系统传感单元选择与配置、硬件电路设计和软件设计。针对铁饼竞技运动对数据精度的要求,通过对陀螺仪静态漂移误差的分析,给出一种补偿MTi陀螺仪随机漂移误差的Kalman算法。利用数字铁饼可以定量分析铁饼投掷过程中的运动特征,为运动员训练提供科学的依据。
第2.2.1条 水平基本模数应为1M。1M数列应按100mm进级,其幅度应由1M至20M。
第2.2.2条 竖向基本模数应为1M。1M数列应按100mm进级,其幅度应由1M至36M。
第2.2.3条 水平扩大模数的幅度,应符合下列规定:
一、3M数列按300mm进级,其幅度应由3M至75M;
二、6M数列按600mm进级,其幅度应由6M至96M;
三、12M数列按1200mm进级,其幅度应由12M至120M;
四、15M数列按1500mm进级,其幅度应由15M至120M;
五、30M数列按3000mm进级,其幅度应由30M至360M;
六、60M数列按6000mm进级,其幅度应由60M至360M等,必要时幅度不限制。
第2.2.4条 竖向扩大模数的幅度,应符合下列规定:
一、3M数列按300mm进级,幅度不限制;
二、6M数列按600mm进级,幅度不限制。
第2.2.5条 分模数的幅度,应符合下列规定:
一、1/10M数列按10mm进级,其幅度应由1/10M至2M;
二、1/5M数列按20mm进级,其幅度应由1/5M至4M;
三、1/2M数列按50mm进级,其幅度应由1/2M至10M。
第三节 模数数列的适用范围
第2.3.1条 水平基本模数1M至20M的数列,应主要用于门窗洞口和构配件截面等处。
第2.3.2条 竖向基本模数1M至36M的数列,应主要用于建筑物的层高、门窗洞口和构配件截面等处。
第2.3.3条 水平扩大模数3M、6M、12M、15M、30M、60M的数列,应主要用于建筑物的开间或柱距、进深或跨度、构配件尺寸和门窗洞口等处。
第2.3.4条 竖向扩大模数3M数列,应主要用于建筑物的高度、层高和门窗洞口等处。
第2.3.5条 分模数1/10M、1/5M、1/2M的数列,应主用于缝隙、构造节点、构配件截面等处。
分模数不应用于确定模数化网格的距离,但根据设计需要分模数可用于确定模数化网格平移的距离。
递归数列: 一种用归纳方法给定的数列。
递归数列举例:例如,等比数列可以用归纳方法来定义,先定义第一项 a1 的值( a1 ≠ 0 ),对 于以后的项 ,用递推公式an 1=qan (q≠0,n=1,2,…)给出定义。一般地,递归数列的前k项a1,a2,…,ak为已知数,从第k 1项起,由某一递推公式an k=f(an,an 1,…,an k-1) ( n=1,2,…)所确定。k称为递归数列的阶数。例如 ,已知 a1=1,a2=1,其余各项由公式an 1=an an-1(n=2,3,…)给定的数列是二阶递归数列。这是斐波那契数列,各项依次为 1 ,1 ,2 ,3,5 ,8 ,13 ,21 ,…,同样 ,由递归式an 1-an =an-an-1( a1,a2 为已知,n=2,3,… ) 给定的数列,也是二阶递归数列,这是等差数列。
约束最优化问题就是求目标函数
约束最优化问题的解法有两种:
例1 最大面积 设长方形的长、宽之和等于
解: 这就是一个约束最优化问题:设长方形的长为x,宽为y,求目标函数A=xy在条件x y=a之下的最大值。
由于从约束条件x y=a中容易解出y=a-x,代入目标函数
由
从上述例子可以看出化约束最优化问题为无约束最优化问题的思路:从约束条件
但是,这种方法有局限性,因为有时从约束条件
这一方法的思路是:把求约束最优化问题转化为求无约束最优化问题,看它应该满足什么样的条件"para" label-module="para">
设
为了便于记忆,并能容易地写出方程组(1),我们构造一个函数
于是,我们把用拉格朗日乘数法求解约束最优化问题的步骤归纳如下:
①构造拉格朗日函数
②解方程组
③根据实际问题的性质,在可能极值点处求极值 。2100433B