给定一个数组,任务是找到从第一个元素开始的最大和交替子序列的和。在这里,交替序列是指先减小,然后增大,然后减小,…。例如10、5、14、3是交替序列。
请注意,此处的反向类型(递增–递减–递增-…)在此不视为交替。
例子:
Input : arr[] = {4, 3, 8, 5, 3, 8}
Output : 28
Explanation:
The alternating subsequence (starting with first element)
that has above maximum sum is {4, 3, 8, 5, 8}
Input : arr[] = {4, 8, 2, 5, 6, 8}
Output : 14
The alternating subsequence (starting with first element)
that has above maximum sum is {4, 2, 8}
此问题类似于最长增加子序列(LIS)问题。可以使用动态编程解决。
Create two empty array that store result of maximum
sum of alternate sub-sequence
inc[] : inc[i] stores results of maximum sum alternating
subsequence ending with arr[i] such that arr[i]
is greater than previous element of the subsequence
dec[] : dec[i] stores results of maximum sum alternating
subsequence ending with arr[i] such that arr[i]
is less than previous element of the subsequence
Include first element of 'arr' in both inc[] and dec[]
inc[0] = dec[0] = arr[0]
// Maintain a flag i.e. it will makes the greater
// elements count only if the first decreasing element
// is counted.
flag = 0
Traversal two loops
i goes from 1 to n-1
j goes 0 to i-1
IF arr[j] > arr[i]
dec[i] = max(dec[i], inc[j] + arr[i])
// Denotes first decreasing is found
flag = 1
ELSE IF arr[j] < arr[i] && flag == 1
inc[i] = max(inc[i], dec[j]+arr[i]);
Final Last Find maximum value inc[] and dec[] .
以下是上述想法的实现。
C/C++
// C++ program to find sum of maximum
// sum alternating sequence starting with
// first element.
#include
using namespace std;
// Return sum of maximum sum alternating
// sequence starting with arr[0] and is first
// decreasing.
int maxAlternateSum(int arr[], int n)
{
if (n == 1)
return arr[0];
// create two empty array that store result of
// maximum sum of alternate sub-sequence
// stores sum of decreasing and increasing
// sub-sequence
int dec[n];
memset(dec, 0, sizeof(dec));
// store sum of increasing and decreasing sun-sequence
int inc[n];
memset(inc, 0, sizeof(inc));
// As per question, first element must be part
// of solution.
dec[0] = inc[0] = arr[0];
int flag = 0 ;
// Traverse remaining elements of array
for (int i=1; i arr[i])
{
dec[i] = max(dec[i], inc[j]+arr[i]);
// Revert the flag , if first decreasing
// is found
flag = 1;
}
// If next element is greater but flag should be 1
// i.e. this element should be counted after the
// first decreasing element gets counted
else if (arr[j] < arr[i] && flag == 1)
// If current sub-sequence is increasing
// then update inc[i]
inc[i] = max(inc[i], dec[j]+arr[i]);
}
}
// find maximum sum in b/w inc[] and dec[]
int result = INT_MIN;
for (int i = 0 ; i < n; i++)
{
if (result < inc[i])
result = inc[i];
if (result < dec[i])
result = dec[i];
}
// return maximum sum alternate sun-sequence
return result;
}
//Driver program
int main()
{
int arr[]= {8, 2, 3, 5, 7, 9, 10};
int n = sizeof(arr)/sizeof(arr[0]);
cout << "Maximum sum = "
<< maxAlternateSum(arr , n ) << endl;
return 0;
}
Java
// Java program to find sum of maximum
// sum alternating sequence starting with
// first element.
public class GFG
{
// Return sum of maximum sum alternating
// sequence starting with arr[0] and is first
// decreasing.
static int maxAlternateSum(int arr[], int n)
{
if (n == 1)
return arr[0];
// create two empty array that store result of
// maximum sum of alternate sub-sequence
// stores sum of decreasing and increasing
// sub-sequence
int dec[] = new int[n];
// store sum of increasing and decreasing sun-sequence
int inc[] = new int[n];
// As per question, first element must be part
// of solution.
dec[0] = inc[0] = arr[0];
int flag = 0 ;
// Traverse remaining elements of array
for (int i=1; i arr[i])
{
dec[i] = Math.max(dec[i], inc[j]+arr[i]);
// Revert the flag , if first decreasing
// is found
flag = 1;
}
// If next element is greater but flag should be 1
// i.e. this element should be counted after the
// first decreasing element gets counted
else if (arr[j] < arr[i] && flag == 1)
// If current sub-sequence is increasing
// then update inc[i]
inc[i] = Math.max(inc[i], dec[j]+arr[i]);
}
}
// find maximum sum in b/w inc[] and dec[]
int result = Integer.MIN_VALUE;
for (int i = 0 ; i < n; i++)
{
if (result < inc[i])
result = inc[i];
if (result < dec[i])
result = dec[i];
}
// return maximum sum alternate sun-sequence
return result;
}
// Driver Method
public static void main(String[] args)
{
int arr[]= {8, 2, 3, 5, 7, 9, 10};
System.out.println("Maximum sum = " +
maxAlternateSum(arr , arr.length));
}
}
Python3
# Python3 program to find sum of maximum
# sum alternating sequence starting with
# first element.
# Return sum of maximum sum alternating
# sequence starting with arr[0] and is
# first decreasing.
def maxAlternateSum(arr, n):
if (n == 1):
return arr[0]
# Create two empty array that
# store result of maximum sum
# of alternate sub-sequence
# Stores sum of decreasing and
# increasing sub-sequence
dec = [0 for i in range(n + 1)]
# store sum of increasing and
# decreasing sun-sequence
inc = [0 for i in range(n + 1)]
# As per question, first element
# must be part of solution.
dec[0] = inc[0] = arr[0]
flag = 0
# Traverse remaining elements of array
for i in range(1, n):
for j in range(i):
# IF current sub-sequence is decreasing the
# update dec[j] if needed. dec[i] by current
# inc[j] + arr[i]
if (arr[j] > arr[i]):
dec[i] = max(dec[i], inc[j] + arr[i])
# Revert the flag, if first
# decreasing is found
flag = 1
# If next element is greater but flag should be 1
# i.e. this element should be counted after the
# first decreasing element gets counted
elif (arr[j] < arr[i] and flag == 1):
# If current sub-sequence is
# increasing then update inc[i]
inc[i] = max(inc[i], dec[j] + arr[i])
# Find maximum sum in b/w inc[] and dec[]
result = -2147483648
for i in range(n):
if (result < inc[i]):
result = inc[i]
if (result < dec[i]):
result = dec[i]
# Return maximum sum
# alternate sun-sequence
return result
# Driver program
arr = [8, 2, 3, 5, 7, 9, 10]
n = len(arr)
print("Maximum sum = ",
maxAlternateSum(arr , n ))
# This code is contributed by Anant Agarwal.
C#
// C# program to find sum of maximum
// sum alternating sequence starting with
// first element.
using System;
class GFG {
// Return sum of maximum
// sum alternating
// sequence starting with
// arr[0] and is first
// decreasing.
static int maxAlternateSum(int []arr, int n)
{
if (n == 1)
return arr[0];
// create two empty array that
// store result of maximum sum
// of alternate sub-sequence
// stores sum of decreasing
// and increasing sub-sequence
int []dec = new int[n];
// store sum of increasing and
// decreasing sun-sequence
int []inc = new int[n];
// As per question, first
// element must be part
// of solution.
dec[0] = inc[0] = arr[0];
int flag = 0 ;
// Traverse remaining elements of array
for (int i = 1; i < n; i++)
{
for (int j = 0; j < i; j++)
{
// IF current sub-sequence
// is decreasing the
// update dec[j] if needed.
// dec[i] by current
// inc[j] + arr[i]
if (arr[j] > arr[i])
{
dec[i] = Math.Max(dec[i],
inc[j] + arr[i]);
// Revert the flag , if
// first decreasing
// is found
flag = 1;
}
// If next element is greater
// but flag should be 1
// i.e. this element should
// be counted after the
// first decreasing element
// gets counted
else if (arr[j] < arr[i] && flag == 1)
// If current sub-sequence
// is increasing then update
// inc[i]
inc[i] = Math.Max(inc[i],
dec[j] + arr[i]);
}
}
// find maximum sum in b/w
// inc[] and dec[]
int result = int.MinValue;
for (int i = 0 ; i < n; i++)
{
if (result < inc[i])
result = inc[i];
if (result < dec[i])
result = dec[i];
}
// return maximum sum
// alternate sun-sequence
return result;
}
// Driver Method
public static void Main()
{
int []arr= {8, 2, 3, 5, 7, 9, 10};
Console.Write("Maximum sum = " +
maxAlternateSum(arr , arr.Length));
}
}
// This code is contributed by Nitin Mittal.
PHP
$arr[$i])
{
$dec[$i] = max($dec[$i], $inc[$j] +
$arr[$i]);
// Revert the flag , if first
// decreasing is found
$flag = 1;
}
// If next element is greater but flag
// should be 1 i.e. this element should
// be counted after the first decreasing
// element gets counted
else if ($arr[$j] < $arr[$i] && $flag == 1)
// If current sub-sequence is increasing
// then update inc[i]
$inc[$i] = max($inc[$i], $dec[$j] +
$arr[$i]);
}
}
// find maximum sum in b/w inc[] and dec[]
$result = -(PHP_INT_MAX - 1);
for ($i = 0 ; $i < $n; $i++)
{
if ($result < $inc[$i])
$result = $inc[$i];
if ($result < $dec[$i])
$result = $dec[$i];
}
// return maximum sum alternate sun-sequence
return $result;
}
// Driver Code
$arr = array(8, 2, 3, 5, 7, 9, 10);
$n = sizeof($arr);
echo "Maximum sum = ",
maxAlternateSum($arr, $n );
// This code is contributed by Ryuga
?>
输出:
Maximum sum = 25
时间复杂度: O(n 2 )
辅助空间: O(n)