非相邻值的最大总和

Posted

技术标签:

【中文标题】非相邻值的最大总和【英文标题】:Maximum sum of non-adjacent values 【发布时间】:2018-11-15 08:02:28 【问题描述】:

我在论坛上找到了几个解决这个问题的方法,但似乎没有一个对我有帮助。主要是因为我找到了一种解决方案,但不知道它的工作原理和原因。

问题说明:对于给定的正整数数组,找出不相邻元素的最大和。

该问题还严格规定解决方案必须在线性时间内。这是我发现的:

int max1 = 0 
int max2 = a[0];

int i;
for(i = 1; i<n; i++)
    int new_max1 = max(max2, max1);
    max2 = max1 + a[i];
    max1 = new_max1;

return max(max1, max2);

谁能帮助澄清这个解决方案?

【问题讨论】:

您是否尝试用铅笔写下一个玩具示例,看看算法在这种情况下的表现如何? 是的,事实上我做了多个例子。仍然无法捕捉到模式。 @koy 第一个设备动态编程方法。我会选择自下而上的方法。该解决方案将占用 O(n) 空间,O(n) 时间。然后,我将通过维护当前和下一个变量来进一步优化空间。您的代码也是如此,但我建议您不要强迫自己学习这 1 个单一的解决方案,而应该使用您自己的解决方案。如果你能做到这一点,你也会明白这一点。 @Koy 试试这个。将 max1 重命名为 max_without_last_element 并将 max2 重命名为 max_with_last_element。一旦你重命名了变量,看看你是否理解这个程序。 【参考方案1】:

想想这几个问题:

P1i:求包含第 i 个的 Array[0:i+1] 的非相邻元素的最大和。P2i:求非相邻元素的最大和Array[0:i+1] 的相邻元素不包含第 i 个。

其中Array[i,j]Array 的子集,从第 i 个跨越到第 (j-1) 个。

想想如何根据P1i, P2i 解决P1(i+1), P2(i+1)

你已经完成了!

更明确地说:

基本情况 (i=0) 是 Array[0], i

那么对于 i=1,P11, P21 的解决方案是 (Array[1] + P10), P20

那么对于 i=2,P12, P22 的解决方案是 (Array[2] + P21), P11

那么对于 i=3,P13, P23 的解决方案是 (Array[3] + P22), P12

那么对于 i=4,P14, P24 的解决方案是 (Array[3] + P23), P13

...

您正在寻找的解决方案是max(P1(n-1), P2(n-1))

您发布的代码是迭代的。它可以很容易地以递归形式重写。玩得开心!

【讨论】:

【参考方案2】:

这是一个动态编程/递归解决方案,它基本上着眼于每个位置的 2 个场景,是否包含或排除一个值。 由于数组中的所有值都是正数,因此该解决方案有效。 如果数组包含负值,此解决方案将不起作用。

arr = Array of numbers
af = function(currentIndex, cummulativeSum)
 if (currentIndex >= arr.length) return cummulativeSum

return Math.max(af(currentIndex+2,cummulativeSum+arr[currentIndex]), af(currentIndex+1, cummulativeSum))

【讨论】:

以上是关于非相邻值的最大总和的主要内容,如果未能解决你的问题,请参考以下文章

c_cpp 最大总和使得没有两个元素相邻

c_cpp 从正整数数组中找出子序列的最大总和,其中任意两个子序列彼此不相邻i

c_cpp 非连续子序列的最大总和

最大化矩阵中“非重叠”数字的总和

使用带有扭曲的javascript找到最大总和

获取 3D numpy 数组中沿轴的连续非 nans 值总和的最大值