最大子段和问题
算法分析与设计作业参考答案

算法分析与设计作业参考答案《算法分析与设计》作业参考答案作业⼀⼀、名词解释:1.递归算法:直接或间接地调⽤⾃⾝的算法称为递归算法。
2.程序:程序是算法⽤某种程序设计语⾔的具体实现。
⼆、简答题:1.算法需要满⾜哪些性质?简述之。
答:算法是若⼲指令的有穷序列,满⾜性质:(1)输⼊:有零个或多个外部量作为算法的输⼊。
(2)输出:算法产⽣⾄少⼀个量作为输出。
(3)确定性:组成算法的每条指令清晰、⽆歧义。
(4)有限性:算法中每条指令的执⾏次数有限,执⾏每条指令的时间也有限。
2.简要分析分治法能解决的问题具有的特征。
答:分析分治法能解决的问题主要具有如下特征:(1)该问题的规模缩⼩到⼀定的程度就可以容易地解决;(2)该问题可以分解为若⼲个规模较⼩的相同问题,即该问题具有最优⼦结构性质;(3)利⽤该问题分解出的⼦问题的解可以合并为该问题的解;(4)该问题所分解出的各个⼦问题是相互独⽴的,即⼦问题之间不包含公共的⼦问题。
3.简要分析在递归算法中消除递归调⽤,将递归算法转化为⾮递归算法的⽅法。
答:将递归算法转化为⾮递归算法的⽅法主要有:(1)采⽤⼀个⽤户定义的栈来模拟系统的递归调⽤⼯作栈。
该⽅法通⽤性强,但本质上还是递归,只不过⼈⼯做了本来由编译器做的事情,优化效果不明显。
(2)⽤递推来实现递归函数。
(3)通过Cooper 变换、反演变换能将⼀些递归转化为尾递归,从⽽迭代求出结果。
后两种⽅法在时空复杂度上均有较⼤改善,但其适⽤范围有限。
三、算法编写及算法应⽤分析题: 1.冒泡排序算法的基本运算如下: for i ←1 to n-1 dofor j ←1 to n-i do if a[j]交换a[j]、a[j+1];分析该算法的时间复杂性。
答:排序算法的基本运算步为元素⽐较,冒泡排序算法的时间复杂性就是求⽐较次数与n 的关系。
(1)设⽐较⼀次花时间1;(2)内循环次数为:n-i 次,(i=1,…n ),花时间为:∑-=-=in j i n 1)(1(3)外循环次数为:n-1,花时间为:2.设计⼀个分治算法计算⼀棵⼆叉树的⾼度。
国际信息学奥林匹克竞赛2023题解

国际信息学奥林匹克竞赛(International Olympiad in Informatics,简称IOI)是一项面向高中生的信息学竞赛,旨在促进全球信息学教育和人才培养。
每年都会有来自世界各地的优秀学生参加这一盛事,并通过解决一系列复杂的编程问题来展示他们的才华。
作为一项高级的信息学竞赛,IOI赛题往往涉及到算法和数据结构的深度思考,考验选手在编程能力和解决问题能力上的造诣。
2023年国际信息学奥林匹克竞赛的题目更是备受瞩目,接下来我们就来深度剖析这些题目并提供解题思路。
第一道题目:“字符串排列”题目描述:给定一个长度为n的字符串s,求出它的所有排列方式,并将其按字典序输出。
解题思路:1. 我们可以利用递归的方法来求解字符串的全排列。
具体地,可以将字符串s的第一个字符与后面的字符依次交换,然后对剩下的字符串进行全排列,直到交换完成一次排列。
这样就可以得到字符串s所有的排列方式。
2. 在程序设计的过程中,我们要注意剪枝操作,可以通过设定一个标志数组来记录某个字符是否已经被使用过,从而避免重复排列的情况。
这道题目的解法较为经典,通过深入的逻辑分析和编程技巧,可以很好地完成题目要求。
第二道题目:“最大子段和”题目描述:给定一个长度为n的整数序列,求出其连续子段的和的最大值。
解题思路:1. 一个直观的解法是利用动态规划来解决这个问题。
具体地,我们可以设置一个dp数组,dp[i]表示以第i个数结尾的最大子段和,然后通过递推式dp[i] = max(nums[i], dp[i-1]+nums[i])来更新dp数组。
2. 在实现过程中,我们要注意处理边界情况和初始化操作,以及在遍历过程中及时更新最大子段和的值。
这道题目需要考虑到较多的边界情况和递推关系,是一道非常有挑战性的动态规划问题。
总结回顾:国际信息学奥林匹克竞赛2023的题目涵盖了递归、动态规划等多个领域,对选手的算法能力和编程功底提出了很高的要求。
算法(复习题)1

平均情况:设待查找的元素在数组中的概率为P,不在数组中的概率为1-P,若出现在数组中每个位置的概率是均等的为p/nT(n)=P1D1+P2D2+...+PiDi+(1-P)Dn+1=p/2+n(1-p/2)1.叙述分治算法和动态规划算法的基本思想,并比较两种算法的异同。
答:分治法将待求解的问题划分成K个较小规模的子问题,对这K个子问题分别求解,再将子问题的解合并为一个更大规模的问题的解,自底向上逐步求出原问题的解. 动态规划将待求解的问题分解成若干的子问题,自底向上地通过求解子问题的解得到原问题的解。
动态规划将每个子问题只求解一次并将其解保存在一个表格中,当需要再次求解此子问题时,只是简单的通过查表过的该子问题的解,避免了大量的重复计算.异同:分治法求解的问题分解后的子问题都是独立的,而使用动态规划求解的问题分解后得到的子问题往往不是相互独立的。
分治法是自顶向下用递归的方法解决问题,而动态规划则是自底向上非递归解决问题。
1.简述分治算法求解过程的三个阶段。
答:(1)划分:既然是分治,当然需要把规模为n的原问题划分为k个规模较小的子问题,并尽量使这k个子问题的规模大致相同。
(2)求解子问题:各子问题的解法与原问题的解法通常是相同的,可以用递归的方法求解各个子问题,有时递归处理也可以用循环来实现。
(3)合并:把各个子问题的解合并起来,合并的代价因情况不同有很大差异,分治算法的有效性很大程度上依赖于合并的实现。
2.叙述分治法的基本思想,并分析分治法与减治法二者的区别。
答:分治法将待求解的问题划分成K个较小规模的子问题,对这K个子问题分别求解,再将子问题的解合并为一个更大规模的问题的解,自底向上逐步求出原问题的解.区别:分治法是把一个大问题划分成若干个子问题,分别求解各个子问题,然后把子问题的解进行合并并得到原问题的解。
减治法同样是把一个大问题划分成若干个子问题,但是这些子问题不需要分别求解,只需求解其中的一个子问题,因而也无需对子问题的解进行合并。
最大子段和问题的简单算法

最大子段和问题的简单算法一、引言最大子段和问题(Maximum Subarray Sum Problem)是计算机科学中一个经典的问题,旨在寻找数组中的连续子数组,使得该子数组中所有元素的总和最大。
这个问题的解决方法有多种,其中包括暴力解法、分治法、动态规划等。
本篇文章将介绍一种简单且高效的解决方法——Kadane算法。
二、算法描述Kadane算法是一种基于动态规划的贪心算法,其基本思想是对于给定的数组,不断选择以当前元素结尾的最大子段和,然后将这个最大子段和更新为全局最大子段和。
算法的主要步骤如下:1. 初始化两个变量,一个是局部最大和max_ending_here,初值为数组的第一个元素;另一个是全局最大和max_global,初值为数组的第一个元素。
2. 遍历数组中的每个元素,对于当前元素,计算以当前元素结尾的最大子段和max_ending_here,然后更新全局最大和max_global。
3. 在遍历过程中,对于每个元素,都会计算出一个以该元素结尾的最大子段和,因此遍历结束后,全局最大和就是最大的子段和。
三、算法复杂度分析Kadane算法的时间复杂度为O(n),其中n是数组的长度。
因为我们需要遍历数组中的每个元素一次。
在空间复杂度方面,Kadane算法只需要常数级别的额外空间来存储两个变量,因此其空间复杂度为O(1)。
四、算法实现下面是一个用Python实现的Kadane算法:def max_subarray_sum(arr):max_ending_here = max_global = arr[0]for i in range(1, len(arr)):max_ending_here =max(arr[i], max_ending_here + arr[i])max_global =max(max_global, max_ending_here)return max_global五、结论Kadane算法是一种简单且高效的解决最大子段和问题的方法,其时间复杂度为O(n),空间复杂度为O(1)。
区间dp知识点总结

区间dp知识点总结区间动态规划以区间为基本单位,将区间问题分解为子区间问题,并通过子问题的优化解来求解原问题的最优解。
在区间动态规划中,我们通常会先对区间进行预处理,然后进行状态转移和最优解的计算,最终得出整个区间的最优解。
本文将介绍区间动态规划的基本概念、相关术语、常用技巧和应用场景,并以具体的例题进行解析,希望能够帮助读者更好地理解并掌握区间动态规划的相关知识。
一、基本概念1. 区间在区间动态规划中,区间通常是指一段连续的序列,可以是数组、字符串或其他数据结构。
如有一个长度为n的数组,通常我们可以将数组的某个子区间[i, j]表示为数组的一段连续元素,其中i和j分别为区间的左右边界。
2. 状态在区间动态规划中,状态通常用来表示问题的解空间,它是问题的一个关键要素。
状态的选择不同,可能会导致不同的算法解法。
3. 状态转移方程区间动态规划的核心是状态转移方程,它描述了问题的状态如何转移,以及如何通过子问题的最优解来求解原问题的最优解。
状态转移方程通常包括两个方面:状态之间的转移关系和状态的初始值。
4. 最优解区间动态规划通常是要求解区间范围内的最优解问题。
最优解可能是指区间的最大值、最小值、最长子序列等。
二、相关术语1. 最长上升子序列(Longest Increasing Subsequence,简称LIS)最长上升子序列是指一个序列中各个元素都严格递增的子序列,且该子序列的长度最大。
在区间动态规划中,求解最长上升子序列的长度是一个常见的问题。
2. 最大子段和(Maximum Subarray Sum)最大子段和是指一个序列中连续元素的和中最大的值。
在区间动态规划中,求解最大子段和也是一个常见的问题。
3. 背包问题背包问题是一类经典的组合优化问题,它包括 0-1 背包问题、多重背包问题、分组背包问题等。
在区间动态规划中,背包问题的求解也是一个重要的应用场景。
4. 字符串处理字符串处理是区间动态规划中一个重要的应用场景,常见的问题包括编辑距离、最长公共子序列、最长回文子串等。
算法设计与分析复习题整理 (1)

一、基本题:算法:1、程序是算法用某种程序设计语言的具体实现。
2、算法就是一组有穷的序列(规则) ,它们规定了解决某一特定类型问题的一系列运算。
3、算法的复杂性是算法效率的度量,是评价算法优劣的重要依据。
4、算法的“确定性”指的是组成算法的每条指令是清晰的,无歧义的。
5、算法满足的性质:输入、输出、确定性、有限性。
6、衡量一个算法好坏的标准是时间复杂度低。
7、算法运行所需要的计算机资源的量,称为算法复杂性,主要包括时间复杂性和空间复杂性。
8、任何可用计算机求解的问题所需的时间都与其规模有关。
递归与分治:9、递归与分治算法应满足条件:最优子结构性质与子问题独立。
10、分治法的基本思想是首先将待求解问题分解成若干子问题。
11、边界条件与递归方程是递归函数的两个要素。
12、从分治法的一般设计模式可以看出,用它设计出的程序一般是递归算法。
13、将一个难以直接解决的大问题,分解成一些规模较小的相同问题,以便各个击破。
这属于分治法的解决方法。
14、Strassen矩阵乘法是利用分治策略实现的算法。
15、大整数乘积算法是用分治法来设计的。
16、二分搜索算法是利用分治策略实现的算法。
动态规划:17、动态规划算法的两个基本要素是最优子结构性质和重叠子问题性质。
18、下列算法中通常以自底向上的方式求解最优解的是动态规划法。
19、备忘录方法是动态规划算法的变形。
20、最优子结构性质是贪心算法与动态规划算法的共同点。
21、解决0/1背包问题可以使用动态规划、回溯法,其中不需要排序的是动态规划,需要排序的是回溯法。
贪心算法:22、贪心算法总是做出在当前看来最好的选择。
也就是说贪心算法并不从整体最优考虑,它所做出的选择只是在某种意义上的局部最优解。
23、最优子结构性质是贪心算法与动态规划算法的共同点。
24、背包问题的贪心算法所需的计算时间为 O(nlogn) 。
回溯法:25、回溯法中的解空间树结构通常有两种,分别是子集树和排列树。
最大子段和例题
选择题在求解最大子段和的问题时,以下哪种算法的时间复杂度最优?A. 暴力枚举法B. 分治法C. 动态规划法(正确答案)D. 贪心算法(特定情况下)给定数组[-2, 1, -3, 4, -1, 2, 1, -5, 4],其最大子段和是:A. 6B. 7C. 8(正确答案)D. 9最大子段和问题中,若数组所有元素均为负数,则最大子段和为:A. 数组中的最大值B. 数组中的最小值(但仍是负数)C. 0(正确答案,即空子段)D. 不存在使用动态规划求解最大子段和时,状态转移方程通常表示为:A. dp[i] = max(dp[i-1]+a[i], a[i])(正确答案)B. dp[i] = min(dp[i-1]+a[i], a[i])C. dp[i] = dp[i-1] * a[i]D. dp[i] = dp[i-1] + a[i]下列哪个数组的最大子段和等于其所有元素之和?A. [1, -2, 3, -4]B. [-1, -2, -3, -4]C. [1, 2, 3, 4](正确答案)D. [0, -1, -1, 0]在求解最大子段和的分治算法中,如果将问题分为两个子问题,每个子问题的规模大约是原问题的一半,那么合并两个子问题的解的时间复杂度是:A. O(n)B. O(log n)C. O(1)(正确答案)D. O(n2)给定数组[a, b, c, d],若a+b<0且c+d>0,则关于其最大子段和的说法正确的是:A. 最大子段和一定包含a和bB. 最大子段和一定不包含c和dC. 最大子段和可能只包含c和d(正确答案)D. 最大子段和一定是整个数组的和对于一个全为正数的数组,其最大子段和:A. 一定小于数组中的最大值B. 一定等于数组中的最大值C. 一定大于数组中的最大值D. 一定等于数组所有元素之和(正确答案)在动态规划求解最大子段和的过程中,dp[i]表示:A. 以第i个元素结尾的最大子段和(正确答案)B. 以第i个元素开头的最大子段和C. 从第1个元素到第i个元素的最大子段和D. 从第i个元素到最后一个元素的最大子段和。
动态规划——最大子段和
动态规划——最⼤⼦段和⼀、最⼤⼦段和问题给定N个数A1, A2, ... An,从中选出k(k不固定)个连续的数字 Ai, Ai+1, ... Ai+k-1,使得∑i+k−1iAt 达到最⼤,求该最⼤值。
分析求最⼤⼦段和可以⽤多种算法来解决.(1)直接枚举max = 0;for i in [1...n]for j in [i....n]sum = 0;for k in [i...j]sum += A[k]if(sum > max)max = sum//时间复杂度为O(n^3)(2)求 sum[i...j]时,直接利⽤ sum[i...j] = sum[i...j-1] + A[j]来优化max = 0;for i in [1...n]sum = 0for j in [i....n]sum += A[j]if(sum > max)max = sum//时间复杂度为O(n^2)(3)分治法将A1...An⽤⼆分法分为左右两边,则A1...An中的最⼤连续⼦段和可能为三种情况:【1】是A1...An/2中的最⼤连续⼦段和【2】是An/2+1....An中的最⼤连续⼦段和【3】横跨左右两边int MaxSum(int* a, int beg, int end){if (beg == end){return a[beg] > 0? a[beg] :0;}int mid = (beg + end) / 2;int max_left = MaxSum(a, beg, mid);int max_right = MaxSum(a, mid + 1 ,end);int s1 = 0, s2 = 0, m_left = 0, m_right = 0;for(int i = mid; i <= beg; i --){s1 += a[i];if(s1 > m_left)m_left = s1;}for(int i = mid+1; i <= end; i ++){s2 += a[i];if(s2 > m_right)m_right = s2;}int max_sum = max_left;if(max_right > max_sum)max_sum = max_right;if(m_right + m_left > max_sum)max_sum = m_left + m_right;return max_sum;}//时间复杂度为 O(nlogn)(4)动态规划算法⽤动归数组 dp[i]表⽰以Ai结尾的若⼲个连续⼦段的和的最⼤值,则有递推公式:dp[i] = max{dp[i-1] + A[i], A[i]}int max = 0;for(int i = 1; i <= n; i ++){if(dp[i-1] > 0){dp[i] = dp[i-1] + A[i];}else{dp[i] = A[i];}if(dp[i]> max){max = dp[i];}}//时间复杂度为O(n)⼆、最⼤⼦矩阵和问题给定MxN的矩阵,其⼦矩阵R{x1, y1, x2, y2} (x1, y1) 为矩阵左上⾓的坐标,(x2, y2)为矩阵右下⾓的坐标,S(x1,y1,x2,y2)表⽰⼦矩阵R中的数字的和,求所有⼦矩阵的和的最⼤值。
搞笑情感问题段子
搞笑情感问题段子1.问:我爱上了一个很帅的男生,但他是个花心大痞子,怎么办?答:别担心,你只需要准备好一份超级辣的鸡尾酒,在他面前给他展现你的热情和性感,然后再关注其他的男生。
当他发现你已经不再关注他时,他就会不自觉地开始追求你。
最后,你可以选择放弃他或是收买他。
2. 问:我想问问男生们,如果喜欢一个女生,会怎么样去吸引她的注意力?答:如果你想吸引一个女生的注意力,你需要做些特别的事情。
比如,你可以穿上一件很酷的T恤,或是戴上一副很帅气的太阳镜,这样就能在她眼中留下一个深刻的印象。
然后,你可以试着和她聊天,让自己在她面前变得更加有趣。
最后,如果你能适时地送她一份礼物,她就会觉得你是一个非常用心的人,从而被你吸引。
3. 问:我和男朋友的感情一直很好,但最近他似乎变得很冷淡,我该怎么办?答:别担心,这种情况很常见。
你只需要想办法让他重新爱上你就可以了。
一些好的方法包括:给他写一封深情的信,或是制作一个美丽的DIY礼物,或是给他做一顿丰盛的饭菜。
这些行动都可以让他重新感受到你对他的爱和关心。
最后,记得多和他沟通,让他知道你的真实感受,这样他就会更愿意和你分享他的心事。
4. 问:我想追一个女生,但她总是很忙,怎么办?答:如果你想追一个女生,你需要先了解她的生活习惯和工作时间。
如果她总是很忙,你可以试着安排一些适合她的休息时间,并邀请她出去。
比如,你可以带她去看一场电影,或是和她一起去旅游。
如果她觉得这些活动很有趣,她就会更愿意和你约会了。
最后,不要忘记给她留下一个深刻的印象,让她觉得你是一个非常有趣和有魅力的人。
5. 问:我想给我女朋友一个浪漫的惊喜,但不知道应该选择什么样的方式?答:如果你想给你女朋友一个浪漫的惊喜,你可以考虑一些比较特别的方式。
比如,你可以打算一次浪漫的旅行,或是制作一份惊喜的爱情礼物。
另外,你还可以在她的生日或是纪念日时送她一份特别的礼物,这样她就会觉得你非常用心和浪漫。
最后,不要忘记给她留下一个深刻的印象,让她觉得你是非常有趣和有魅力的人。
三种方法求解最大子区间和:DP、前缀和、分治
三种⽅法求解最⼤⼦区间和:DP、前缀和、分治题⽬洛⾕:LeetCode:给出⼀个长度为n的序列a,选出其中连续且⾮空的⼀段使得这段和最⼤。
挺经典的⼀道题⽬,下⾯分别介绍O(n) 的 DP 做法、前缀和做法,以及O(n log n) 的分治做法。
DP 做法⽤d i表⽰结尾为位置i的最⼤区间和,则有d i=max(d i−1,0)+a i问题的答案即为max{d i∣i∈[1,n]}。
编写代码时不需要开d数组,⽤变量 last_d 记录d i−1,变量 ans 记录max{d i},并在扫描时动态更新即可。
时间复杂度O(n),空间复杂度O(1)。
核⼼代码如下:maxn = int(2e5 + 5)arr = [0 for _ in range(maxn)] # 从下标 1 开始存# 输⼊过程略……ans = Nonelast_d = 0for i in range(1, n + 1):temp_ans = max(last_d, 0) + arr[i]if ans is None or temp_ans > ans:ans = temp_anslast_d = temp_ansprint(ans)前缀和做法将数列前n项的和记为sum n:sum n=n ∑i=1a i可以⽤前缀和快速求区间和:y∑i=x a i=sum y−sum x−1⽤d i表⽰结尾为位置i的最⼤区间和,则有d i=sum i−min{sum j∣j<i}问题的答案即为max{d i∣i∈[1,n]}。
编写代码时只需要开前缀和数组,⽆需开d数组,⽤变量 cur_min_pre_sum 记录min{sum j},变量 ans 记录max{d i},并动态维护即可。
时间复杂度O(n),空间复杂度O(n)。
核⼼代码如下:maxn = int(2e5 + 5)arr = [0 for _ in range(maxn)] # 原数组,从下标 1 开始存pre_sum = [0 for _ in range(maxn)] # 前缀和数组# 输⼊过程略……# 预处理前缀和for i in range(1, n + 1):pre_sum[i] = pre_sum[i - 1] + arr[i]cur_min_pre_sum = 0ans = Nonefor i in range(1, n + 1):temp_ans = pre_sum[i] - cur_min_pre_sumif ans is None or temp_ans > ans:ans = temp_anscur_min_pre_sum = min(cur_min_pre_sum, pre_sum[i])print(ans)分治做法若有⼀区间 [start,stop),区间中点为mid,其最⼤⼦段和对应的⼦区间为 [i,j),则 [i,j) 只有以下三种情况:[i,j) 完全在左⼦区间 [start,mid) 内;[i,j) 完全在右⼦区间 [mid,stop) 内;[i,j) 横跨中点mid。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
ifb>0
b=b+v(i);
else
b=v(i);
end
end
R3=sum
调用函数:
v=[-20 11 -4 13 -5 -2];
tic;
MaxSum1(v)
toc;
tic;
MaxSum1(v)
toc;
tic
MaxSum3(v)
toc;
一十、运行结果
实验五:最大子段和问题
一、实验环境
windows xp
Matlab R2010b
二、实验内容
给定由n个整数组成的序列(a1, a2,…, an),求该序列形如的子段和的最大值,当所有整数均为负整数时,其最大子段和为0。
三、实验目的
(1)深刻掌握动态规划法的设计思想并能熟练运用;
(2)理解这样一个观点:同样的问题可以用不同的方法解决,一个好的算法是反复努力和重新修正的结果。
v=[-20 11 -4 13 -5 -2]
20
0.011056
20
0.001512
20
0.009128
v=[5 11 -4 -1 5 -2]
16
0.004243
16
0.001234
16
0.003662
v=[5 -11 4 -1 5 2]
10
0.004712
10
0.001274
10
0.003066
v=[-8 -14 14 -12 5 2]
4.比较left和right
4.1如果left==right
4.2则判断v(left)>0?
4.3如果大于0,则sum=v(left);
4.4否则sum=0;
算法三(动态规划法):
可能会有许多可行解。每一个解都对应于一个值,我们希望找到具有最优值的解。动态规划算法与分治法类似,其基本思想也是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解。。
伪代码:算法MaxSum3(v)
输入:一组数列v
输出:最大字段和
1.sum=0;
2.计算数组长度n=length(v);
3.循环i从1—n
3.1如果b>0则b=b+v(i);
3.2否则b=v(i);
3.3如果b>sum则sum=b;
六、实验结果:
用Excel表格计算其平均值
实验数组
蛮力法
分治法
动态规划
输出:最大字段和及运行时间
1.sum=0;
2.计算数组长度n=length(v);
3.循环i从1—n
3.1thissum=0;
3.2循环j从i—n
3.2.1thissum=thissum+v(j);
3.2.2如果thissum>sum,则sum=thissum;
4.输出最大字段和sum;
算法二(分治法):
n=length(v);
left=v(1);
right=v(n);
ifleft==right
ifv(left)>0
sum=v(left);
else
sum=0;
end
else
center=(left+right)/2;
leftsum=MaxSum(v,left,center);
rightsum=MaxSum(v,center+1,right);
s1=0;
lefts=0;
fori=center:-1:left
c1=c1+1;
lefts=lefts+a(i);
iflefts>s1
s1=lefts;
end
end
s2=0;
rights=0;
forj=center+1:1:right
c1=c1+1;
rights=rights+a(j);
ifrights>s2
s2=rights;
end
end
sum=s1+s2;
ifsum<leftsum
sum=leftsum;
ifsum<rightsum
sum=rightsum;
end
end
end
R2=sum
算法三(动态规划法):
functionMaxSum3(v)%动态规划法O(n)
sum=0;
b=0;
n=length(v);
14
0.003990
14
0.00124
14
0.003062
平均时间
0.0060002
0.001315
0.0047295
七、实验结果分析:
通过时间复杂度的分析,可以看出动态规划算法是最优的,其次是分治算法,最差的是蛮力算法,从计数得到的结果与预期的结果一致。
但是本次试验出现的问题是在计时器里显示的数据分治算法的用时比蛮力算法的长,我认为造成这种结果的因素有两个:
1、实验数据特殊,数据样本太小。
2、因为蛮力算法程序只是一个两层循环,而分治算法的代码过长,导致我们的计时器得到的结果产生错误。
八、实验结论:
根据自己程序的算法的分析得到时间复杂性如下
蛮力算法:O(n2)
分治算法:O(nlog n )
动态规划:O(n)
九、程序源代码
算法一(蛮力法):
functionMaxSum1(v)%蛮力法O(n^2)
(3)分别用蛮力法、分治法和动态规划法设计最大子段和问题的算法;
(4)比较不同算法的时间性能;
(5)给出测试数据,写出程序文档。
四、问题分析
求最大子段和问题主要有3种方法,
1.蛮力法
2.分治法
3.动态规划法
五、算法描述:
算法一(蛮力法):
从一个数开始,逐个相加比较大小。
伪代码:算法MaxSum1
输入:一组数列v
sum=0;
n=length(v);
fori=1:1:n
thissum=0;
forj=i:1:n;
thissum=thissum+v(j);
ifthissum>sum
sum=thissum;
end
end
end
R1=sum
算法二(分治法):
functionMaxSum2(v)%分治法O(nlogn)
sum=0;
R1 =
20
Elapsed time is 0.011056 seconds.
R1 =
20
Elapsed time is 0.001512 seconds.
R3 =
20
Elapsed time is 0.009128 seconds.
分--将问题分解为规模更小的子问题;
治--将这些规模更小的子问题逐个击破;
合--将已解决的子问题合并,最终得出“母”问题的解;。
伪代码:算法MaxSum2(v)
输入:一组数列v
输出:最大字段和
1.sum=0;
2.计算数组长度n=length(v);
3.设置两部分的初始值left=v(1),right=v(n);