01-复杂度2 maximum subsequence sum
时间: 2023-04-28 20:00:24 浏览: 135
最大子序列和问题是一个经典的算法问题,它的目标是在一个序列中找到一个子序列,使得该子序列的元素之和最大。
这个问题可以使用动态规划算法来解决。具体来说,可以定义一个数组dp,其中dp[i]表示以第i个元素结尾的最大子序列和。则dp[i]的值可以通过以下递推式计算得到:
dp[i] = max(dp[i-1]+nums[i], nums[i])
其中nums[i]表示原序列中的第i个元素。递推式的含义是:要么将当前元素加入前面的子序列中,要么从当前元素开始重新构建一个新的子序列。
最终,我们可以通过遍历dp数组找到最大的dp[i]值,即为原序列的最大子序列和。
该算法的时间复杂度为O(n),其中n为原序列的长度。
相关问题
01-复杂度2 maximum subsequence sum (25 分)
题目描述
给定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++ 代码
1007 maximum subsequence sum (25 分)
题目描述
给定K个整数组成的序列{ N1, N2, ..., NK},“连续子列”被定义为{ Ni, Ni+1, ..., Nj},其中 1≤i≤j≤K。“最大子列和”则被定义为所有连续子列元素的和中最大者。例如给定序列{-2, 11, -4, 13, -5, -2},其连续子列{ 11, -4, 13}有最大的和20。现要求你编写程序,计算给定整数序列的最大子列和。
输入格式
输入第1行给出正整数K(≤100000)。第2行给出K个整数,其间以空格分隔。
输出格式
在一行中输出最大子列和。如果序列中所有整数皆为负数,则输出0。
输入样例
6
-2 11 -4 13 -5 -2
输出样例
20
思路分析
本题是最大子序列和问题,可以使用动态规划来解决。设dp[i]表示以第i个数结尾的最大子序列和,则有状态转移方程:dp[i] = max(dp[i-1]+a[i], a[i]),其中a[i]表示第i个数。
时间复杂度:O(n)
空间复杂度:O(n)
代码实现
阅读全文