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++
#include <bits/stdc++.h>
using namespace std;
int MaxSumBS( int arr[], int n)
{
int max_sum = INT_MIN;
int MSIBS[n], MSDBS[n];
for ( int i = 0; i < n; i++) {
MSDBS[i] = arr[i];
MSIBS[i] = arr[i];
}
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];
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];
for ( int i = 0; i < n; i++)
max_sum = max(max_sum, (MSDBS[i] + MSIBS[i] - arr[i]));
return max_sum;
}
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
import java.io.*;
class GFG {
static int MaxSumBS( int arr[], int n)
{
int max_sum = Integer.MIN_VALUE;
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];
}
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];
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];
for ( int i = 0 ; i < n; i++)
max_sum = Math.max(max_sum, (MSDBS[i] + MSIBS[i] - arr[i]));
return max_sum;
}
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));
}
}
|
Python3
def max_sum(arr, n):
MSIBS = arr[:]
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]
MSDBS = arr[:]
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" )
for i, j, k in zip (MSIBS, MSDBS, arr):
max_sum = max (max_sum, i + j - k)
return max_sum
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()
|
C#
using System;
class GFG {
static int MaxSumBS( int [] arr, int n)
{
int max_sum = int .MinValue;
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];
}
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];
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];
for ( int i = 0; i < n; i++)
max_sum = Math.Max(max_sum, (MSDBS[i] + MSIBS[i] - arr[i]));
return max_sum;
}
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));
}
}
|
PHP
<?php
function MaxSumBS( $arr , $n )
{
$max_sum = PHP_INT_MIN;
$MSIBS = array ();
$MSDBS = array ();
for ( $i = 0; $i < $n ; $i ++)
{
$MSDBS [ $i ] = $arr [ $i ];
$MSIBS [ $i ] = $arr [ $i ];
}
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 ];
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 ];
for ( $i = 0; $i < $n ; $i ++)
$max_sum = max( $max_sum , ( $MSDBS [ $i ] +
$MSIBS [ $i ] -
$arr [ $i ]));
return $max_sum ;
}
$arr = array (1, 15, 51, 45, 33,
100, 12, 18, 9);
$n = count ( $arr );
echo "Maximum Sum : " ,
MaxSumBS( $arr , $n );
?>
|
Javascript
<script>
function MaxSumBS(arr, n)
{
let max_sum = Number.MIN_VALUE;
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];
}
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];
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];
for (let i = 0; i < n; i++)
max_sum =
Math.max(max_sum, (MSDBS[i] + MSIBS[i] - arr[i]));
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>
|
Time Complexity: O(n2)
Auxiliary Space: O(n)
Last Updated :
20 Mar, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...