这是最大子数组和算法的动态编程版本的工作方式吗?
Is this the way the dynamic programming version of maximum subarray sum algorithm works?
在我的算法教科书的dynamic programming
章中,我有一个如何使用这种技术解决最大子数组和问题的示例。我不确定我是否得到了算法背后的想法,所以我将在这里描述我认为它是如何工作的(在阅读了几次关于它并做了几个例子之后)。
基本上,您有一个大小为 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);
}
人们不需要总是递归来实现动态编程。Kadane 算法是动态规划的一个简单示例,通过将问题分解为重用 n-1 次的子问题(将迄今为止最后一个最大子数组与当前 n -1 次进行比较)。
相关文章:
- 此动态编程问题的自上而下方法
- 使用动态编程以有限的资金选择活动
- 返回不停止函数,递归函数问题?(编程练习,动态规划,Levenshtein 回溯)
- 寻找解决这个动态编程问题的提示
- 为什么其中一个斐波那契序列的动态编程实现比另一个更快
- 不明白为什么动态编程在这里不起作用
- 如何解决在使用动态 2D 数组进行矩阵乘法的 MPI 进行并行编程时的问题
- 如何在动态编程中选择缓存的初始值?
- 今天的主流编程语言主要使用动态还是静态(词汇)作用域?
- C 编程,动态内存无法使用Malloc和Calloc正常工作
- 使用动态编程解决的 C++ 平台
- 元编程:动态声明一个新结构
- C :动态编程,给定3个可能的操作
- 使用动态编程计算二项式系数
- C++中TSP的动态编程解决方案
- 动态编程中这种初始化背后的直觉
- 有没有办法在函数以编程方式返回的引用上多次调用函数? -元组动态访问
- 葡萄酒选择动态编程
- 双递归动态编程
- 带1D阵列USACO培训的动态编程:子集总和