01-复杂度2 maximum subsequence sum (25 分)
时间: 2023-04-30 22:00:18 浏览: 134
复杂度测试1
题目描述
给定K个整数组成的序列{ N1, N2, ..., NK },“连续子列”被定义为{ Ni, Ni+1, ..., Nj },其中 1≤i≤j≤K。“最大子列和”则被定义为所有连续子列元素的和中最大者。例如给定序列{-2, 11, -4, 13, -5, -2},其最大子列和为20,对应子列为{ 11, -4, 13 }。
现在你应该给出一个算法,计算给定整数序列的最大子列和。
输入格式
输入第1行给出正整数K(K≤10000),第2行给出K个整数,其间以空格分隔。
输出格式
在一行中输出最大子列和。如果序列中所有整数皆为负数,则输出。
输入样例
6
-2 11 -4 13 -5 -2
输出样例
20
算法1
(暴力枚举) $O(n^2)$
暴力枚举所有的子序列,计算它们的和,最后找到最大的和即可。
时间复杂度
枚举所有子序列,时间复杂度为$O(n^2)$。
C++ 代码
算法2
(分治) $O(nlogn)$
将序列分成左右两部分,最大子序列和可能在左边、右边或者跨越中间。如果最大子序列和在左边或者右边,那么可以递归求解;如果最大子序列和跨越中间,那么可以分别求出左边的最大后缀和和右边的最大前缀和,然后将它们相加即可。
时间复杂度
每次递归都会将序列分成两部分,时间复杂度为$O(logn)$,而每次计算跨越中间的最大子序列和的时间复杂度为$O(n)$,所以总的时间复杂度为$O(nlogn)$。
C++ 代码
算法3
(动态规划) $O(n)$
用dp[i]表示以i结尾的最大子序列和,那么dp[i]的值可以由dp[i-1]和a[i]计算得到。如果dp[i-1]是负数,那么dp[i]就是a[i];否则dp[i]就是dp[i-1]+a[i]。最后找到dp数组中的最大值即可。
时间复杂度
只需要遍历一遍数组,时间复杂度为$O(n)$。
C++ 代码
阅读全文