给定具有正和负条目的数组vector<int> arr
,最大连续子序列问题需要找到具有最大总和的数组arr
的(连续)段。空段的总和为零。我使用的算法的C ++代码如下:
int MaxContSum(const vector<int>& arr){
int i,sum=0,max=0;
for(i=0;i<arr.size();i++){
if(arr[i]>=0) {if(sum<0) sum=0;}
else {if(sum>max) max=sum;}
sum+=arr[i];
}
if(sum>max) max=sum; return max;
}
这个算法是贪心算法还是动态编程?看起来它只是逐个扫描条目,并根据arr[i]
是否为正面或负面,一种本地可检查的条件应用不同的策略。为什么这个问题出现在动态编程章节中呢?
答案 0 :(得分:1)
这是Kadane's algorithm for the maximum subarray problem。它扫描序列并跟踪一般到此迭代时找到的最大子阵列总和,并且最大子阵列总和恰好在此时结束。它是如何知道子阵列的起始位置导致最佳总结到这一点?每当1)前一个和为负数,并且2)遇到一个正元素时,从正元素开始并从那里继续是有效的。它的工作原理是简单的归纳。
这个算法不贪心,但可以看作是动态编程。
贪婪的算法进行局部最佳猜测,并坚持下去(只是继续进行)。在这里,相反,算法可以猜测检查从某个点开始的子序列(其中以正元素结束的和为负),然后丢弃它并尝试从某个其他点开始的子序列(同样,因为总和变为负数)元素是积极的。)
相反,它可以被视为动态编程问题。正如维基百科条目所说:
由于此算法使用最佳子结构的方式(在每个位置结束的最大子阵列以相对但较小且重叠的子问题的简单方式计算:最后一个子阵列在前一个位置结束)此算法可被视为一个动态编程的简单例子。
答案 1 :(得分:0)
为了有资格使用DP解决问题,应该有两个主要属性:
根据您的介绍,第一个属性肯定是缺失的,因此我不会将此算法归类为DP。另一方面,您使用较小问题的计算结果来获得最终结果 - 因此我们有最佳子结构,这可能是您在动态编程章节中找到此算法的原因,即使它不属于那里。