Maximum sum alternating subsequence (original) (raw)

Last Updated : 11 Sep, 2023

Given an array, the task is to find sum of maximum sum alternating subsequence starting with first element. Here alternating sequence means first decreasing, then increasing, then decreasing, ... For example 10, 5, 14, 3 is an alternating sequence.
Note that the reverse type of sequence (increasing - decreasing - increasing -...) is not considered alternating here.
Examples:

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}

This problem is similar to Longest Increasing Subsequence (LIS) problem. and can be solved using Dynamic Programming.

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[] .

Below is implementation of above idea.
Note:- For the case where the first element of the array is the smallest element in the array. The output will be the first element only. This is an edge case that need to be checked. Taking a variable and initializing it with the first value of the array and then comparing it with other values will find the min. Check if the min is equal to arr[0]. If it is true then arr[0] is to be returned, because there is no decreasing step available to find an alternating subsequence.

C++ `

// C++ program to find sum of maximum // sum alternating sequence starting with // first element. #include <bits/stdc++.h> 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]; // handling the edge case int min = arr[0]; for (int i = 1; i < n; i++) { if (min > arr[i]) min = arr[i]; } if (min == arr[0]) { 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 sub-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 < 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] = 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 sub-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]; // handling the edge case int min = arr[0]; for (int i = 1; i < n; i++) { if (min > arr[i]) min = arr[i]; } if (min == arr[0]) { 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
    // sub-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 = 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 sub-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]
min = arr[0]
for i in range(1, n):
    if(min > arr[i]):
        min = arr[i]
if(arr[0] == min):
    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 sub-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
        else if (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 sub-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];
    // handling the edge case
    int min = arr[0];
    for (int i = 1; i < n; i++) {
        if (min > arr[i])
            min = arr[i];
    }
    if (min == arr[0]) {
        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 sub-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 sub-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

min=min = min=arr[0]; for ($i = 1; i<i < i<n; $i++) { min=max(min = max(min=max(min,$arr[$i]);} if($arr[0]==$min) 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=arrayfill(0,dec = array_fill(0, dec=arrayfill(0,n, 0); // store sum of increasing and // decreasing sub-sequence inc=arrayfill(0,inc = array_fill(0, inc=arrayfill(0,n, 0); // As per question, first element // must be part of solution. dec[0]=dec[0] = dec[0]=inc[0] = $arr[0]; $flag = 0; // Traverse remaining elements of array for ($i = 1; i<i < i<n; $i++) { for ($j = 0; j<j < 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[arr[arr[i]) { dec[dec[dec[i] = max($dec[$i], inc[inc[inc[j] + arr[arr[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[arr[arr[i] && $flag == 1) // If current sub-sequence is increasing // then update inc[i] inc[inc[inc[i] = max($inc[$i], dec[dec[dec[j] + arr[arr[arr[i]); } } // find maximum sum in b/w inc[] and dec[] $result = -(PHP_INT_MAX - 1); for ($i = 0 ; i<i < i<n; $i++) { if ($result < inc[inc[inc[i]) result=result = result=inc[$i]; if ($result < dec[dec[dec[i]) result=result = result=dec[$i]; } // return maximum sum alternate sub-sequence return $result; } // Driver Code $arr = array(8, 2, 3, 5, 7, 9, 10); n=sizeof(n = sizeof(n=sizeof(arr); echo "Maximum sum = ", maxAlternateSum($arr, $n ); // This code is contributed by Ryuga ?>

JavaScript

`

Time Complexity : O(n2)
Auxiliary Space : O(n)