给定一个正数数组,请找到一个子序列的最大和,并约束该序列中的任何2个数字都不应与该数组相邻。所以3 2 7 10应该返回13(3和10之和),或者3 2 5 10 7应该返回15(3、5和7之和)。以最有效的方式回答问题。
例子 :
Input : arr[] = {5, 5, 10, 100, 10, 5}
Output : 110
Input : arr[] = {1, 2, 3}
Output : 4
Input : arr[] = {1, 20, 3}
Output : 20
算法:
循环访问arr []中的所有元素,并维护两个和incl和excl,其中incl =包括前一个元素的最大和,而excl =除去前一个元素的最大和。
排除当前元素的最大和为max(incl,excl),包括当前元素的最大和为excl + current元素(请注意,仅考虑excl是因为元素不能相邻)。
在循环结束时,返回最大值incl和excl。
例子:
arr[] = {5, 5, 10, 40, 50, 35}
incl = 5
excl = 0
For i = 1 (current element is 5)
incl = (excl + arr[i]) = 5
excl = max(5, 0) = 5
For i = 2 (current element is 10)
incl = (excl + arr[i]) = 15
excl = max(5, 5) = 5
For i = 3 (current element is 40)
incl = (excl + arr[i]) = 45
excl = max(5, 15) = 15
For i = 4 (current element is 50)
incl = (excl + arr[i]) = 65
excl = max(45, 15) = 45
For i = 5 (current element is 35)
incl = (excl + arr[i]) = 80
excl = max(65, 45) = 65
And 35 is the last element. So, answer is max(incl, excl) = 80
感谢Debanjan提供代码。
执行:
C/C++
#include
/*Function to return max sum such that no two elements
are adjacent */
int FindMaxSum(int arr[], int n)
{
int incl = arr[0];
int excl = 0;
int excl_new;
int i;
for (i = 1; i < n; i++)
{
/* current max excluding i */
excl_new = (incl > excl)? incl: excl;
/* current max including i */
incl = excl + arr[i];
excl = excl_new;
}
/* return max of incl and excl */
return ((incl > excl)? incl : excl);
}
/* Driver program to test above function */
int main()
{
int arr[] = {5, 5, 10, 100, 10, 5};
int n = sizeof(arr) / sizeof(arr[0]);
printf("%d n", FindMaxSum(arr, n));
return 0;
}
Java
class MaximumSum
{
/*Function to return max sum such that no two elements
are adjacent */
int FindMaxSum(int arr[], int n)
{
int incl = arr[0];
int excl = 0;
int excl_new;
int i;
for (i = 1; i < n; i++)
{
/* current max excluding i */
excl_new = (incl > excl) ? incl : excl;
/* current max including i */
incl = excl + arr[i];
excl = excl_new;
}
/* return max of incl and excl */
return ((incl > excl) ? incl : excl);
}
// Driver program to test above functions
public static void main(String[] args)
{
MaximumSum sum = new MaximumSum();
int arr[] = new int[]{5, 5, 10, 100, 10, 5};
System.out.println(sum.FindMaxSum(arr, arr.length));
}
}
// This code has been contributed by Mayank Jaiswal
Python
# Function to return max sum such that
# no two elements are adjacent
def find_max_sum(arr):
incl = 0
excl = 0
for i in arr:
# Current max excluding i (No ternary in
# Python)
new_excl = excl if excl>incl else incl
# Current max including i
incl = excl + i
excl = new_excl
# return max of incl and excl
return (excl if excl>incl else incl)
# Driver program to test above function
arr = [5, 5, 10, 100, 10, 5]
print find_max_sum(arr)
# This code is contributed by Kalai Selvan
C#
/* Program to return max sum such that no
two elements are adjacent */
using System;
class GFG {
/* Function to return max sum such
that no two elements are adjacent */
static int FindMaxSum(int []arr, int n)
{
int incl = arr[0];
int excl = 0;
int excl_new;
int i;
for (i = 1; i < n; i++)
{
/* current max excluding i */
excl_new = (incl > excl) ?
incl : excl;
/* current max including i */
incl = excl + arr[i];
excl = excl_new;
}
/* return max of incl and excl */
return ((incl > excl) ?
incl : excl);
}
// Driver program to test above
// functions
public static void Main()
{
int []arr = new int[]{5, 5, 10,
100, 10, 5};
Console.Write(
FindMaxSum(arr, arr.Length));
}
}
// This code has been contributed by
// nitin mittal
PHP
$excl)? $incl: $excl;
// current max including i
$incl = $excl + $arr[$i];
$excl = $excl_new;
}
// return max of incl and excl
return (($incl > $excl)? $incl : $excl);
}
// Driver Code
$arr = array(5, 5, 10, 100, 10, 5);
$n = sizeof($arr);
echo FindMaxSum($arr, $n);
// This code is contributed by Ajit
?>
输出:
110
时间复杂度: O(n)
有关更多说明,请参阅从房屋中查找最大可能的盗窃价值。
现在,也对带有负数的数组尝试同样的问题。