经典算法——求最大子序列和.docx_第1页
经典算法——求最大子序列和.docx_第2页
经典算法——求最大子序列和.docx_第3页
经典算法——求最大子序列和.docx_第4页
经典算法——求最大子序列和.docx_第5页
已阅读5页,还剩1页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

经典算法求最大子序列和比较经典的算法问题,能够很好的体现动态规划的实现,以一点“画龙点睛” 大大精简了算法复杂度,且实现简单。本文中实现了4种:一般 maxSubSequenceSum0 O(n3)简单优化过的算法 maxSubSequenceSum1 O(n2)分治法优化的算法 maxSubSequenceSum2 O(n*log(n)动态规划的算法 maxSubSequenceSum3 O(n)#include #include mymath.h/* 计算序列的某段子序列的和,maxSubSequenceSum0使用*/static int subSequenceSum(int a, int left, int right) int i, sum = 0; for (i = left; i = right; i+) sum = sum + ai; return sum;/* 三层遍历求子序列和的最大值,算法复杂度O(n3)*/int maxSubSequenceSum0(int a, int len) int i, j; int curSum; /* 当前序列和 */ int maxSum; /* 最大序列和 */ /* 初始化最大子序列和为序列第一个元素 */ maxSum = a0; /* 第一层循环定义子序列起始位置 */ for (i = 0; i len; i+) /* 起始位置为i,初始化当前和为0 */ curSum = 0; /* 第二层循环定义子序列结束位置 */ for (j = i; j maxSum) maxSum = curSum; return maxSum;/* 双层遍历求子序列和的最大值,算法复杂度O(n2)*/int maxSubSequenceSum1(int a, int len) int i, j; int curSum; /* 当前序列和 */ int maxSum; /* 最大序列和 */ /* 初始化最大子序列和为序列第一个元素 */ maxSum = a0; /* 外层循环定义子序列起始位置 */ for (i = 0; i len; i+) /* 起始位置为i,初始化当前和为0 */ curSum = 0; /* 内层循环定义子序列结束位置 */ for (j = i; j maxSum) maxSum = curSum; return maxSum;/* 某段字序列中,含左边界元素的字序列和中的最大值,_maxSubSequenceSum2中使用*/static int _maxLeftBoderSubSequenceSum(int a, int left, int right) int i; int sum = 0; int maxSum = aleft; for (i = left; i maxSum) maxSum = sum; return maxSum;/* 某段字序列中,含右边界元素的字序列和中的最大值,_maxSubSequenceSum2中使用*/static int _maxRightBoderSubSequenceSum(int a, int left, int right) int i; int sum = 0; int maxSum = aright; for (i = right; i = left; i-) sum += ai; if (sum maxSum) maxSum = sum; return maxSum;/* 求序列某段子序列中子序列和最大值*/static int _maxSubSequenceSum2(int a, int left, int right) int center; int leftMaxSum; int rightMaxSum; int maxLeftBorderSum; int maxRightBorderSum; /* 递归终止条件 */ if (left = right) return aleft; /* 分治法递归开始,取中点二分处理 */ center = (left + right) 1; /* center = (left + right) / 2; */ /* 递归求左右子序列段中最大子序列和 */ leftMaxSum = _maxSubSequenceSum2(a, left, center); rightMaxSum = _maxSubSequenceSum2(a, center + 1, right); maxLeftBorderSum = _maxRightBoderSubSequenceSum(a, left, center); maxRightBorderSum = _maxLeftBoderSubSequenceSum(a, center + 1, right); /* * 二分后的最大值有三个: * 1、leftMaxSum,左段最大子序列和 * 2、rightMaxSum,右段最大子序列和 * 3、maxLeftBorderSum+maxRightBorderSum,左段最大含右边界子序列和最大值和右段最大含左边界子序列和最大值,二者之和 * 这三者中的最大值即为分段前的最大子序列和 * * 分治算法核心部分,解决分治后结果归并问题,具体分析: * 这是对分段后的子序列的一种划分,有三种,只需分别求出各种的最大值然后在三者之间取一个最大值即可: * 1、子序列全在左段,最大子序列和为leftMaxSum * 2、子序列全在右段,最大子序列和为rightMaxSum * 3、子序列跨左右段,最大字序列和为maxLeftBorderSum+maxRightBorderSum */ return tmax(leftMaxSum, rightMaxSum, maxLeftBorderSum+maxRightBorderSum);/* 分治法实现,算法复杂度O(n*log(n)* 分:使用二分法进行分段* 治:详细算法见_maxSubSequenceSum2内描述,简述为:* 全段最大子序列为以下三者中的最大值* 左段最大子序列和* 右段最大子序列和* 左段最大含右边界子序列和最大值和右段最大含左边界子序列和最大值之和*/int maxSubSequenceSum2(int a, int len) return _maxSubSequenceSum2(a, 0, len - 1);/* 动态规划实现,算法复杂度O(n)*/int maxSubSequenceSum3(int a, int len) int i; int curSum; /* 当前序列和 */ int maxSum; /* 最大序列和 */ /* 初始化当前序列和为0 */ curSum = 0; /* 初始化最

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论