最大字段和问题

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

最大字段和问题

1.实验题目

给定由N 个整数(可能有负整数)组成的序列(1a ,2a ,…,n a ),求该序列形如∑=j i k k a

的子段和的最大值,当所有整数均为负整数是,其最大子段和为0。

2.实验目的

(1)深刻掌握动态规划法的设计思想并能熟练运用;

(2)理解这样一个观点:同样的问题可以用不同的方法解决,一个好的算法是反复努力和重新修正的结果。

3.实验分析

蛮力法:利用3个for 的嵌套(实现从第1个数开始计算子段长度为1,2,3…n 的子

段和,同理计算出第2个数开始的长度为1,2,3…n-1的子段和,依次类推到第n 个数开始计算的长为1的子段和)和一个if (用来比较大小),将其所有子段的和计算出来并将最大子段和赋值给summax1。

用了3个for 嵌套所以时间复杂性为○(n 3)。

分治法:

(1)划分:按照平衡子问题的原则,将序列(1a ,2a ,…,

n a )划分成长度相同的两个字序列(1a ,…,⎣⎦2/n a )和(⎣⎦12/+n a ,…,n a )。

(2)求解子问题:对于划分阶段的情况分别的两段可用递归求解,如果最大子段和在

两端之间需要分别计算

s1=⎣⎦⎣⎦)2/1(max 2/n i a n i k k ≤≤∑=,

s2=⎣⎦⎣⎦)2/(max 12/n j n a j n k k

≤≤∑+=,

则s1+s2为最大子段和。若然只在左边或右边,那就好办了,前者视s1为summax2,后者视s2 o summax2。

(3)合并:比较在划分阶段的3种情况下的最大子段和,取三者之中的较大者为原问

题的解。

(4)时间复杂性分析: f(n) = 2*f(n/2) + ○(n/2), 最后为○(nlogn)。

动态规划法:

动态规划法求解最大字段和问题的关键是要确定动态规划函数。记

)1(max )(1n j a j b i i k k j i ≤≤⎭

⎬⎫⎩⎨⎧=∑=≤≤ 则

{})(max max max max 1111j b a a n j j i k k j i n j j

i k k n j i ≤≤=≤≤≤≤=≤≤≤=⎭⎬⎫⎩⎨⎧=∑∑ 由b (j )的定义,当b (j-1)>0是,b (j )=b (j-1)+a ,否则,b (j )=a 。可得如下递推式:

)1()(0

)1(0)1()1({n j j b j b j b a j b a j j ≤≤=>-≤-+-

代码实现过程中只用了一个for, 时间复杂性为:○(n)

三种方法写在同一cpp 上,比较其时间,由于分治法和动态规划法,要用比较比长的序列,故把程序设计成有手动输入和随机输入,对于随机生成函数rand()只生成正数,故引入了rand()/13-1129,使其既有正数生成,也有负数生成。程序运行如下:

首先先用手动输入:

由于要比较时间,故要用到大量数据,所以用随机输入:

至于序列在此不作输出,若输出将会造成截屏不方便,

可见蛮力法只可以处理小理的数据。

当数据量超过10000时,由蛮力法要等很久才输出,所先把蛮力去掉,就比较分治法和动态

规划法:

明显可以动态规划法所用的时间要少。

相关文档
最新文档