【发布时间】:2015-09-05 23:51:01
【问题描述】:
在我的算法教科书中的dynamic programming 章节中,我有一个如何使用这种技术解决maximum sub array sum problem 的示例。我不确定我是否理解了算法背后的想法,所以我将在这里描述我认为它是如何工作的(在阅读了几次关于它并做了几个例子之后)。
基本上,您有一个大小为n 的数组A,并且您想找到该数组的最大子数组和。总和最大的子数组可以位于数组的右半部分、左半部分或中间的某个位置。因此,您递归调用该函数以从左侧计算最大子数组总和,然后从数组右侧计算。然后,计算从数组中间到末尾的最大子数组和,然后计算从数组中间到开头的最大子数组和(它的长度不一定是n/2)。然后,如果左边的最大子数组和加上右边的最大子数组和的和大于左半边的最大子数组和(递归计算的那个)和右半边的最大子数组和(也递归计算),则最大子数组和在中间。否则是左半部分和右半部分的最大值(这些是递归计算的)。
我得到算法的工作机制了吗?
这是我正在分析的函数:
int maxSubArraySum(int* arr, int n)
{
if(n == 1)
{
return arr[0];
}
int m = n / 2;
int left = maxSubArraySum(arr, m);
int right = maxSubArraySum(arr + m, n - m);
int leftsum = INT_MIN, rightsum = INT_MIN, sum = 0;
for(int i = m; i < n; i++)
{
sum += arr[i];
rightsum = std::max(rightsum, sum);
}
sum = 0;
for(int i = (m - 1); i >= 0; i--)
{
sum += arr[i];
leftsum = std::max(leftsum, sum);
}
int retval = std::max(left, right);
return std::max(retval, leftsum + rightsum);
}
【问题讨论】:
-
不幸的是,没有。这一点都不像最大子数组算法。说真的,没有任何相似之处。
-
@user2357112 你的意思是我的描述还是功能?
-
实际上,这应该是如何使用动态编程的示例,还是动态编程可以改进的次优算法示例?因为虽然它与 Kadane 的算法(动态规划解决方案)没有任何相似之处,但它仍然是解决问题的有效算法。它只是不是动态编程,也没有动态编程那么快。
-
好吧,你已经成功地描述了你所看到的算法。如果这个描述应该被其他人阅读,而不仅仅是为了帮助你理解算法,一些部分可能应该不那么模棱两可,但描述是准确的。
-
虽然这个算法没有像我通常期望的那样多的子问题重用被描述为动态的东西,但我想它可以这样看待。它绝对不会重做子问题,回想起来,虽然 Kadane 的算法要快得多,但我不确定它是否真的重用了子问题结果更多。
标签: c++ algorithm dynamic-programming sub-array