Maximum sum alternating subsequence

3.6

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

C/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];

   // 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<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 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<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 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));
	}
}


Output:

Maximum sum = 25

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

This article is contributed by Sahil Chhabra(KILLER). If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.

GATE CS Corner    Company Wise Coding Practice

Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.

Recommended Posts:



3.6 Average Difficulty : 3.6/5.0
Based on 11 vote(s)










Writing code in comment? Please use ide.geeksforgeeks.org, generate link and share the link here.