Maximum sum Bi-tonic Sub-sequence
Given an array of integers. A subsequence of arr[] is called Bitonic if it is first increasing, then decreasing.
Examples :
Input : arr[] = {1, 15, 51, 45, 33, 100, 12, 18, 9} Output : 194 Explanation : Bi-tonic Sub-sequence are : {1, 51, 9} or {1, 51, 100, 18, 9} or {1, 15, 51, 100, 18, 9} or {1, 15, 45, 100, 12, 9} or {1, 15, 45, 100, 18, 9} .. so on Maximum sum Bi-tonic sub-sequence is 1 + 15 + 51 + 100 + 18 + 9 = 194 Input : arr[] = {80, 60, 30, 40, 20, 10} Output : 210
This problem is a variation of standard Longest Increasing Subsequence (LIS) problem and longest Bitonic Sub-sequence.
We construct two arrays MSIBS[] and MSDBS[]. MSIBS[i] stores the sum of the Increasing subsequence ending with arr[i]. MSDBS[i] stores the sum of the Decreasing subsequence starting from arr[i]. Finally, we need to return the max sum of MSIBS[i] + MSDBS[i] – Arr[i].
Step-by-step approach of the above idea:
- Start with an array of integers arr and its length n.
- Initialize two arrays MSIBS and MSDBS of length n with the values of arr.
- Compute the values of MSIBS from left to right by iterating through each element i and comparing it with all elements before it. If arr[i] > arr[j] and MSIBS[i] < MSIBS[j] + arr[i], then update MSIBS[i] to MSIBS[j] + arr[i].
- Compute the values of MSDBS from right to left by iterating through each element i and comparing it with all elements after it. If arr[i] > arr[j] and MSDBS[i] < MSDBS[j] + arr[i], then update MSDBS[i] to MSDBS[j] + arr[i].
- Find and return the maximum value of MSIBS[i] + MSDBS[i] – arr[i] for all i.
Pseudocode:
function MaxSumBS(arr, n): max_sum = INT_MIN MSIBS = [arr[i] for i in range(n)] MSDBS = [arr[i] for i in range(n)] for i from 1 to n-1: for j from 0 to i-1: if arr[i] > arr[j] and MSIBS[i] < MSIBS[j] + arr[i]: MSIBS[i] = MSIBS[j] + arr[i] for i from n-2 to 0: for j from n-1 to i+1: if arr[i] > arr[j] and MSDBS[i] < MSDBS[j] + arr[i]: MSDBS[i] = MSDBS[j] + arr[i] for i from 0 to n-1: max_sum = max(max_sum, MSIBS[i] + MSDBS[i] - arr[i]) return max_sum
Below is the implementation of above idea
C++
// C++ program to find maximum sum of bi-tonic sub-sequence #include <bits/stdc++.h> using namespace std; // Function return maximum sum of Bi-tonic sub-sequence int MaxSumBS( int arr[], int n) { int max_sum = INT_MIN; // MSIBS[i] ==> Maximum sum Increasing Bi-tonic // subsequence ending with arr[i] // MSDBS[i] ==> Maximum sum Decreasing Bi-tonic // subsequence starting with arr[i] // Initialize MSDBS and MSIBS values as arr[i] for // all indexes int MSIBS[n], MSDBS[n]; for ( int i = 0; i < n; i++) { MSDBS[i] = arr[i]; MSIBS[i] = arr[i]; } // Compute MSIBS values from left to right */ for ( int i = 1; i < n; i++) for ( int j = 0; j < i; j++) if (arr[i] > arr[j] && MSIBS[i] < MSIBS[j] + arr[i]) MSIBS[i] = MSIBS[j] + arr[i]; // Compute MSDBS values from right to left for ( int i = n - 2; i >= 0; i--) for ( int j = n - 1; j > i; j--) if (arr[i] > arr[j] && MSDBS[i] < MSDBS[j] + arr[i]) MSDBS[i] = MSDBS[j] + arr[i]; // Find the maximum value of MSIBS[i] + MSDBS[i] - arr[i] for ( int i = 0; i < n; i++) max_sum = max(max_sum, (MSDBS[i] + MSIBS[i] - arr[i])); // return max sum of bi-tonic sub-sequence return max_sum; } // Driver program int main() { int arr[] = { 1, 15, 51, 45, 33, 100, 12, 18, 9 }; int n = sizeof (arr) / sizeof (arr[0]); cout << "Maximum Sum : " << MaxSumBS(arr, n); return 0; } |
Java
// java program to find maximum // sum of bi-tonic sub-sequence import java.io.*; class GFG { // Function return maximum sum // of Bi-tonic sub-sequence static int MaxSumBS( int arr[], int n) { int max_sum = Integer.MIN_VALUE; // MSIBS[i] ==> Maximum sum Increasing Bi-tonic // subsequence ending with arr[i] // MSDBS[i] ==> Maximum sum Decreasing Bi-tonic // subsequence starting with arr[i] // Initialize MSDBS and MSIBS values as arr[i] for // all indexes int MSIBS[] = new int [n]; int MSDBS[] = new int [n]; for ( int i = 0 ; i < n; i++) { MSDBS[i] = arr[i]; MSIBS[i] = arr[i]; } // Compute MSIBS values from left to right */ for ( int i = 1 ; i < n; i++) for ( int j = 0 ; j < i; j++) if (arr[i] > arr[j] && MSIBS[i] < MSIBS[j] + arr[i]) MSIBS[i] = MSIBS[j] + arr[i]; // Compute MSDBS values from right to left for ( int i = n - 2 ; i >= 0 ; i--) for ( int j = n - 1 ; j > i; j--) if (arr[i] > arr[j] && MSDBS[i] < MSDBS[j] + arr[i]) MSDBS[i] = MSDBS[j] + arr[i]; // Find the maximum value of MSIBS[i] + // MSDBS[i] - arr[i] for ( int i = 0 ; i < n; i++) max_sum = Math.max(max_sum, (MSDBS[i] + MSIBS[i] - arr[i])); // return max sum of bi-tonic // sub-sequence return max_sum; } // Driver program public static void main(String[] args) { int arr[] = { 1 , 15 , 51 , 45 , 33 , 100 , 12 , 18 , 9 }; int n = arr.length; System.out.println( "Maximum Sum : " + MaxSumBS(arr, n)); } } // This code is contributed by vt_m |
Python3
# Dynamic Programming implementation of maximum sum of bitonic subsequence # Function return maximum sum of Bi-tonic sub-sequence def max_sum(arr, n): # MSIBS[i] ==> Maximum sum Increasing Bi-tonic # subsequence ending with arr[i] # MSDBS[i] ==> Maximum sum Decreasing Bi-tonic # subsequence starting with arr[i] # allocate memory for MSIBS and initialize it to arr[i] for # all indexes MSIBS = arr[:] # Compute MSIBS values from left to right for i in range (n): for j in range ( 0 , i): if arr[i] > arr[j] and MSIBS[i] < MSIBS[j] + arr[i]: MSIBS[i] = MSIBS[j] + arr[i] # allocate memory for MSDBS and initialize it to arr[i] for # all indexes MSDBS = arr[:] # Compute MSDBS values from right to left for i in range ( 1 , n + 1 ): for j in range ( 1 , i): if arr[ - i] > arr[ - j] and MSDBS[ - i] < MSDBS[ - j] + arr[ - i]: MSDBS[ - i] = MSDBS[ - j] + arr[ - i] max_sum = float ( "-Inf" ) # Find the maximum value of MSIBS[i] + MSDBS[i] - arr[i] for i, j, k in zip (MSIBS, MSDBS, arr): max_sum = max (max_sum, i + j - k) # return max sum of bi-tonic sub-sequence return max_sum # Driver program to test the above function def main(): arr = [ 1 , 15 , 51 , 45 , 33 , 100 , 12 , 18 , 9 ] n = len (arr) print ( "Maximum Sum :" , max_sum(arr, n)) if __name__ = = '__main__' : main() # This code is contributed by Neelam Yadav |
C#
// C# program to find maximum // sum of bi-tonic sub-sequence using System; class GFG { // Function return maximum sum // of Bi-tonic sub-sequence static int MaxSumBS( int [] arr, int n) { int max_sum = int .MinValue; // MSIBS[i] ==> Maximum sum Increasing Bi-tonic // subsequence ending with arr[i] // MSDBS[i] ==> Maximum sum Decreasing Bi-tonic // subsequence starting with arr[i] // Initialize MSDBS and MSIBS values as arr[i] for // all indexes int [] MSIBS = new int [n]; int [] MSDBS = new int [n]; for ( int i = 0; i < n; i++) { MSDBS[i] = arr[i]; MSIBS[i] = arr[i]; } // Compute MSIBS values from left to right */ for ( int i = 1; i < n; i++) for ( int j = 0; j < i; j++) if (arr[i] > arr[j] && MSIBS[i] < MSIBS[j] + arr[i]) MSIBS[i] = MSIBS[j] + arr[i]; // Compute MSDBS values from right to left for ( int i = n - 2; i >= 0; i--) for ( int j = n - 1; j > i; j--) if (arr[i] > arr[j] && MSDBS[i] < MSDBS[j] + arr[i]) MSDBS[i] = MSDBS[j] + arr[i]; // Find the maximum value of MSIBS[i] + // MSDBS[i] - arr[i] for ( int i = 0; i < n; i++) max_sum = Math.Max(max_sum, (MSDBS[i] + MSIBS[i] - arr[i])); // return max sum of bi-tonic // sub-sequence return max_sum; } // Driver program public static void Main() { int [] arr = { 1, 15, 51, 45, 33, 100, 12, 18, 9 }; int n = arr.Length; Console.WriteLine( "Maximum Sum : " + MaxSumBS(arr, n)); } } // This code is contributed by vt_m |
PHP
<?php // PHP program to find maximum // sum of bi-tonic sub-sequence function MaxSumBS( $arr , $n ) { $max_sum = PHP_INT_MIN; // MSIBS[i] ==> Maximum sum Increasing // Bi-tonic subsequence ending with arr[i] // MSDBS[i] ==> Maximum sum Decreasing // Bi-tonic subsequence starting with arr[i] // Initialize MSDBS and MSIBS values // as arr[i] for all indexes $MSIBS = array (); $MSDBS = array (); for ( $i = 0; $i < $n ; $i ++) { $MSDBS [ $i ] = $arr [ $i ]; $MSIBS [ $i ] = $arr [ $i ]; } // Compute MSIBS values // from left to right */ for ( $i = 1; $i < $n ; $i ++) for ( $j = 0; $j < $i ; $j ++) if ( $arr [ $i ] > $arr [ $j ] && $MSIBS [ $i ] < $MSIBS [ $j ] + $arr [ $i ]) $MSIBS [ $i ] = $MSIBS [ $j ] + $arr [ $i ]; // Compute MSDBS values // from right to left for ( $i = $n - 2; $i >= 0; $i --) for ( $j = $n - 1; $j > $i ; $j --) if ( $arr [ $i ] > $arr [ $j ] && $MSDBS [ $i ] < $MSDBS [ $j ] + $arr [ $i ]) $MSDBS [ $i ] = $MSDBS [ $j ] + $arr [ $i ]; // Find the maximum value of // MSIBS[i] + MSDBS[i] - arr[i] for ( $i = 0; $i < $n ; $i ++) $max_sum = max( $max_sum , ( $MSDBS [ $i ] + $MSIBS [ $i ] - $arr [ $i ])); // return max sum of // bi-tonic sub-sequence return $max_sum ; } // Driver Code $arr = array (1, 15, 51, 45, 33, 100, 12, 18, 9); $n = count ( $arr ); echo "Maximum Sum : " , MaxSumBS( $arr , $n ); // This code is contributed // by shiv_bhakt. ?> |
Javascript
<script> // JavaScript program to find maximum // sum of bi-tonic sub-sequence // Function return maximum sum // of Bi-tonic sub-sequence function MaxSumBS(arr, n) { let max_sum = Number.MIN_VALUE; // MSIBS[i] ==> Maximum sum Increasing Bi-tonic // subsequence ending with arr[i] // MSDBS[i] ==> Maximum sum Decreasing Bi-tonic // subsequence starting with arr[i] // Initialize MSDBS and MSIBS values as arr[i] for // all indexes let MSIBS = new Array(n); let MSDBS = new Array(n); for (let i = 0; i < n; i++) { MSDBS[i] = arr[i]; MSIBS[i] = arr[i]; } // Compute MSIBS values from left to right */ for (let i = 1; i < n; i++) for (let j = 0; j < i; j++) if (arr[i] > arr[j] && MSIBS[i] < MSIBS[j] + arr[i]) MSIBS[i] = MSIBS[j] + arr[i]; // Compute MSDBS values from right to left for (let i = n - 2; i >= 0; i--) for (let j = n - 1; j > i; j--) if (arr[i] > arr[j] && MSDBS[i] < MSDBS[j] + arr[i]) MSDBS[i] = MSDBS[j] + arr[i]; // Find the maximum value of MSIBS[i] + // MSDBS[i] - arr[i] for (let i = 0; i < n; i++) max_sum = Math.max(max_sum, (MSDBS[i] + MSIBS[i] - arr[i])); // return max sum of bi-tonic // sub-sequence return max_sum; } let arr = [ 1, 15, 51, 45, 33, 100, 12, 18, 9 ]; let n = arr.length; document.write( "Maximum Sum : " + MaxSumBS(arr, n)); </script> |
Maximum Sum : 194
Time Complexity: O(n2)
Auxiliary Space: O(n)
This article is contributed by Nishant_Singh (Pintu). If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.
Please Login to comment...