求最大字段和问题(常规法,分治法,动态规划法)
算法设计与分析-----求最大字段和问题
问题描述:给定由n个整数组成的序列(a1,a2,a3......,an),求该序列的子段的最大值.
常规法:
从a1开始,求出以a1开头的子序列最大的和为sum,依次从a2开始,在sum等于以a1开头的基础上,与以a2开头的不同长度的子序列进行比较,取最大值,然后依次从a3,a4......an开头,最后得到最大子序列的和;
int maxSum(int a[],int n) {int ThisSum,MaxSum=0,i,j,k;for(i=0;i<n;i++){ThisSum=0;for(j=i;j<n;j++){ThisSum+=a[j];if(ThisSum>MaxSum){MaxSum=ThisSum; //每一趟的最大值}}}return MaxSum; }
分治法:
用分治法求最大字段和首先将问题划分,即将一个整序列划分成长度相等的两个序列,这时会出现3种情况,即1,最大字段和在第一个序列, 2最大字段和在第二序列,3,最大字段和在第一个序列和第二个序列之间.然后将这3中情况的最大字段合并,取3者之中的最大值为问题的解.
int Max3(int a,int b,int c) //求三种情况下的最大值; {int max =a;if(max < b) max=b;if(max < c) max=c;return max; } int MaxSubSum(int *a,int fI,int lI) {int i=0;int mI=(fI+lI)>>2; //右移相当于除于2,左移相当于乘于2;int lMax=0,rMax=0,lMaxBorder=0,rMaxBorder=0,lSumBorder=0,rSumBorder=0,max=0;if(fI==lI){return *(a+fI);}lMax=MaxSubSum(a,fI,mI); //对应情况1,递归求解rMax=MaxSubSum(a,mI+1,lI); //对应情况2,递归求解for(i=mI;i>=fI;i--){ //求左边界的最大字段和;lSumBorder+=*(a+i);if(lMaxBorder < lSumBorder){lMaxBorder=lSumBorder; //包括左边界的最大值放在lMaxBorder}}for(i=mI+1;i<=lI;i++){ //求右边界的最大字段和;rSumBorder+=*(a+i);if(rMaxBorder < rSumBorder){rMaxBorder=rSumBorder;}}max=Max3(lMax,rMax,lMaxBorder+rMaxBorder);return max; }
- 动态规划法
设All[i]为子问题A[i...n-1]的连续子序列之和的最大值,start[i]为从A[i]开始的连续之和的最大值,因此:
All[i]=A[n-1] ,当i=n-1时;
All[i]=max{All[i+1],start[i]} i=0,1,2....n-2;
其中start[i]为:
start[i]=A[n-1],当i=n-1时;
start[i]=max{A[i],A[i]+start[i+1]} i=0,1,2,3.....n-2;
代码如下:
int max(int a, int b) { return a > b ? a:b; } int maxSum(int A[], int n) { int All[n], start[n], i; start[n - 1] = All[n - 1] = A[n - 1]; for (i = n - 2;i >= 0;i--) { start[i] = max(A[i], A[i] + start[i + 1]); All[i] = max(All[i + 1], start[i]); } return All[0]; }
下面是对空间复杂度的优化:
int max(int a, int b) { return a > b ? a:b; } int maxSum(int A[], int n) { int start, All, i; start = All = A[n - 1]; for (i = n - 2;i >= 0;i--) { start = max(A[i], A[i] + start); All = max(All, start); } return All; }
时间复杂度为 O(n);
求最大字段和问题(常规法,分治法,动态规划法)相关推荐
- 蛮力法-分治法-处理最近对问题
两种方法对最近对问题的解释 背景描述: 终于,隔了将近一周,开始更新第二篇算法博客.今天的问题是最近对问题.问题描述如下:对于二维坐标系中的若干个点,从中判断出相距最近的两个点,并输出最近的这个距 ...
- 演算法 - 分治法(Divide-and-Conquer)
排版真的乱到一个 ¥*@#&? 一,Divide-and-Conquer(分治法) 二,Recurrences(递归) 1,替代法(Substitution method) 2,Tree Me ...
- C语言实现最大字段和(动态规划法和分治法)
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一.动态规划法 二.分治法 三.程序总代码 总结 前言 本次将对最大字段和使用C语言实现的两种方法实现,动态规划法和分 ...
- 求解最大连续子序列和问题(Java)蛮力法+分治法
求解最大连续子序列和问题 [问题描述] 给定一个有n(n>=1)个整数的序列,要求求出其中最大连续子序列的和. [样例输入] 6 -2 11 -4 13 -5 -2 [样例输出] 20 [问题求 ...
- python求最大值代码的方式_python使用分治法实现求解最大值的方法
本文实例讲述了python使用分治法实现求解最大值的方法.分享给大家供大家参考.具体分析如下: 题目: 给定一个顺序表,编写一个求出其最大值和最小值的分治算法. 分析: 由于顺序表的结构没有给出,作为 ...
- 分治法求金块问题java_十、用分治法求金块问题.doc
十.用分治法求金块问题.doc PAGE PAGE 31 十.用分治法求金块问题: 老板有一袋金块(共n块,n是2的幂(n>=2)),最优秀的雇员得到其中最重的一块,最差的雇员得到其中最轻的一块 ...
- 005-算法-分治法
一.概念: 在计算机科学中,分治法是建基于多项分支递归的一种很重要的算法范式.字面上的解释是"分而治之",就是把一个复杂的问题分成两个或更多的相同或相似的子问题,直到最后子问题可以 ...
- c语言分治法求众数重数_算法实验二 分治法 众数问题.pdf
算法实验二 分治法 众数问题 算法分析与设计实验二 分治法 主要内容 • 实验目的 • 主要实验仪器设备和环境 • 实验内容 • 实验要求 • 注意点 实验目的 • 理解分治法的基本思想 • 针对特定 ...
- 螺旋方阵(列举法,分治法,java版,逆时针)
目录 螺旋方阵介绍 1.适合基础薄弱同学的 列举法 2.螺旋方阵代码 螺旋方阵介绍 所谓"螺旋方阵",是指对任意给定的N,将1到N×N的数字从左上角第1个格子开始,按顺时针螺旋方向 ...
最新文章
- 怎么自己打印餐饮小票_自己怎么做餐饮外卖配送系统?可以开发外卖配送系统的公司有哪些?...
- 常用容器管理器易受危险 exploit 攻击
- js 判断浏览器是否滚动到底部
- python的sorted函数和operator.itemgetter函数
- 2021年,小傅哥の年终总结
- MoleBox PRO build 2.3.054,, Latest , Private Member Build Edition
- LQ735kii针式打印机安装教程以及设置教程超级详细
- 博士申请 | 加拿大阿尔伯塔大学韩杰教授招收电子与计算机专业博士/博后
- 系统分析和设计方法之用户界面设计
- 微弱电流检测放大器PCB布线布局设计
- 语音信号的时域处理(二)
- 【XSY2271】青蛙(栈)
- dir under linux.Linux下的类dir程序.
- JAVA服务端实现页面截屏(附代码)
- “Hack DHS”漏洞猎人在 DHS 系统中发现 122 个安全漏洞
- SpringBoot中属性映射之开启驼峰命名
- 最新Eclipse及Eclipse IDE for Java EE Developers中文汉化和设置中文Doc
- openstack cinder
- I/O复用 poll的内核源码剖析
- 您有一封邀请函!首届中国房地产数字峰会嘉宾亮相丨附最新议程
热门文章
- 泰山OFFICE技术讲座:关于微软雅黑字体,渲染的差异
- QQ发送PDF为什么显示服务器,qq上传输文件默认发送在线文件设置.pdf
- 性格色彩测试android程序开发之四--响应dialog事件的处理
- 2021年4月30日 星期五 阴
- codemirror 光标定位_CodeMirror 中固定滚动位置
- 剧情介绍:“阿甘正传”
- HTML + CSS 实现豆瓣首页
- EZ-Lock易锁 DRM 文件加密保护系统
- python3exe_用cxfreeze打包Python3.3成exe文件
- 微信转发链接不显示图片和描述文字