Maximum sum Bi-tonic Sub-sequence
Last Updated :
20 Mar, 2023
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>
Time Complexity: O(n2)
Auxiliary Space: O(n)
Similar Reads
Maximum Sum Increasing Subsequence Given an array arr[] of n positive integers. The task is to find the sum of the maximum sum subsequence of the given array such that the integers in the subsequence are sorted in strictly increasing order.Examples:Input: arr[] = [1, 101, 2, 3, 100]Output: 106Explanation: The maximum sum of a increas
15+ min read
Maximum Sum Decreasing Subsequence Given an array of N positive integers. The task is to find the sum of the maximum sum decreasing subsequence(MSDS) of the given array such that the integers in the subsequence are sorted in decreasing order. Examples: Input: arr[] = {5, 4, 100, 3, 2, 101, 1} Output: 106 100 + 3 + 2 + 1 = 106 Input:
7 min read
Maximum sum alternating subsequence 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
13 min read
Maximum Balanced Subsequence Score Given a stock's prices for the past n days in the array stockPrice. Choose a subsequence (an ordered subset of an array's elements) of stock prices, called chosenDays, such that the chosen subsequence of stock prices is balanced. The score of the chosen subsequence is the sum of stock prices on the
7 min read
Maximum Sum Subsequence of length k Given an array sequence [A1, A2 ...An], the task is to find the maximum possible sum of increasing subsequence S of length k such that S1<=S2<=S3.........<=Sk. Examples: Input : n = 8 k = 3 A=[8 5 9 10 5 6 21 8] Output : 40 Possible Increasing subsequence of Length 3 with maximum possible s
11 min read