Given an array arr[] and K subarrays in the form (Li, Ri), the task is to find the maximum possible value of
![Rendered by QuickLaTeX.com \sum_{i = 1}^{K} arr[L_i:R_i]](https://www.geeksforgeeks.org/wp-content/ql-cache/quicklatex.com-a5ae165825383166c4470915a6207c7f_l3.png)
. It is allowed to shuffle the array before calculating this value to get the maximum sum.
Examples:
Input: arr[] = {1, 1, 2, 2, 4}, queries = {{1, 2}, {2, 4}, {1, 3}, {5, 5}, {3, 5}}
Output: 26
Explanation:
Shuffled Array to get the maximum sum – {2, 4, 2, 1, 1}
Subarray Sum = arr[1:2] + arr[2:4] + arr[1:3] + arr[5:5] + arr[3:5]
=> 6 + 7 + 8 + 1 + 4 = 26
Input: arr[] = {4, 1, 2, 1, 9, 2}, queries = {{1, 2}, {1, 3}, {1, 4}, {3, 4}}
Output: 49
Explanation:
Shuffled Array to get the maximum sum – {2, 4, 9, 2, 1, 1}
Subarray Sum = arr[1:2] + arr[1:3] + arr[1:4] + arr[3:4]
=> 6 + 15 + 17 + 11 = 49
Naive Approach: A simple solution is to compute the maximum sum of all possible permutations of the given array and check which sequence gives us the maximum summation.
Efficient Approach: The idea is to use Prefix Arrays to find out the frequency of indices over all subarrays. We can do this as follows:
//Initialize an array
prefSum[n] = {0, 0, ...0}
for each Li, Ri:
prefSum[Li]++
prefSum[Ri+1]--
// Find Prefix sum
for i=1 to N:
prefSum[i] += prefSum[i-1]
// prefSum contains frequency of
// each index over all subarrays
Finally, greedily choose the index with the highest frequency and put the largest element of the array at that index. This way we will get the largest possible sum.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int maximumSubarraySum(
int a[], int n,
vector<pair< int , int > >& subarrays)
{
int i, maxsum = 0;
int prefixArray[n] = { 0 };
for (i = 0; i < subarrays.size(); ++i) {
prefixArray[subarrays[i].first - 1]++;
prefixArray[subarrays[i].second]--;
}
for (i = 1; i < n; i++) {
prefixArray[i] += prefixArray[i - 1];
}
sort(prefixArray,
prefixArray + n,
greater< int >());
sort(a, a + n, greater< int >());
for (i = 0; i < n; i++)
maxsum += a[i] * prefixArray[i];
return maxsum;
}
int main()
{
int n = 6;
int a[] = { 4, 1, 2, 1, 9, 2 };
vector<pair< int , int > > subarrays;
subarrays.push_back({ 1, 2 });
subarrays.push_back({ 1, 3 });
subarrays.push_back({ 1, 4 });
subarrays.push_back({ 3, 4 });
cout << maximumSubarraySum(a, n,
subarrays);
}
|
Java
import java.util.*;
import java.lang.*;
class GFG{
static int maximumSubarraySum( int a[], int n,
ArrayList<List<Integer>> subarrays)
{
int i, maxsum = 0 ;
int [] prefixArray = new int [n];
for (i = 0 ; i < subarrays.size(); ++i)
{
prefixArray[subarrays.get(i).get( 0 ) - 1 ]++;
prefixArray[subarrays.get(i).get( 1 )]--;
}
for (i = 1 ; i < n; i++)
{
prefixArray[i] += prefixArray[i - 1 ];
}
Arrays.sort(prefixArray);
Arrays.sort(a);
for (i = 0 ; i < n; i++)
maxsum += a[i] * prefixArray[i];
return maxsum;
}
public static void main (String[] args)
{
int n = 6 ;
int a[] = { 4 , 1 , 2 , 1 , 9 , 2 };
ArrayList<List<Integer>> subarrays = new ArrayList<>();
subarrays.add(Arrays.asList( 1 , 2 ));
subarrays.add(Arrays.asList( 1 , 3 ));
subarrays.add(Arrays.asList( 1 , 4 ));
subarrays.add(Arrays.asList( 3 , 4 ));
System.out.println(maximumSubarraySum(a, n,
subarrays));
}
}
|
Python3
def maximumSubarraySum(a, n, subarrays):
maxsum = 0
prefixArray = [ 0 ] * n
for i in range ( len (subarrays)):
prefixArray[subarrays[i][ 0 ] - 1 ] + = 1
prefixArray[subarrays[i][ 1 ]] - = 1
for i in range ( 1 , n):
prefixArray[i] + = prefixArray[i - 1 ]
prefixArray.sort()
prefixArray.reverse()
a.sort()
a.reverse()
for i in range (n):
maxsum + = a[i] * prefixArray[i]
return maxsum
n = 6
a = [ 4 , 1 , 2 , 1 , 9 , 2 ]
subarrays = [ [ 1 , 2 ], [ 1 , 3 ],
[ 1 , 4 ], [ 3 , 4 ] ]
print (maximumSubarraySum(a, n, subarrays))
|
C#
using System;
using System.Collections.Generic;
class GFG{
static int maximumSubarraySum( int [] a, int n,
List<List< int >> subarrays)
{
int i, maxsum = 0;
int [] prefixArray = new int [n];
for (i = 0; i < subarrays.Count; ++i)
{
prefixArray[subarrays[i][0] - 1]++;
prefixArray[subarrays[i][1]]--;
}
for (i = 1; i < n; i++)
{
prefixArray[i] += prefixArray[i - 1];
}
Array.Sort(prefixArray);
Array.Sort(a);
for (i = 0; i < n; i++)
maxsum += a[i] * prefixArray[i];
return maxsum;
}
static void Main()
{
int n = 6;
int [] a = { 4, 1, 2, 1, 9, 2 };
List<List< int >> subarrays = new List<List< int >>();
subarrays.Add( new List< int >{ 1, 2 });
subarrays.Add( new List< int >{ 1, 3 });
subarrays.Add( new List< int >{ 1, 4 });
subarrays.Add( new List< int >{ 3, 4 });
Console.WriteLine(maximumSubarraySum(a, n,subarrays));
}
}
|
Javascript
<script>
function maximumSubarraySum(a, n, subarrays)
{
let i, maxsum = 0;
let prefixArray = new Array(n);
prefixArray.fill(0);
for (i = 0; i < subarrays.length; ++i)
{
prefixArray[subarrays[i][0] - 1]++;
prefixArray[subarrays[i][1]]--;
}
for (i = 1; i < n; i++)
{
prefixArray[i] += prefixArray[i - 1];
}
prefixArray.sort();
a.sort();
for (i = 0; i < n; i++)
maxsum += a[i] * prefixArray[i];
return maxsum;
}
let n = 6;
let a = [ 4, 1, 2, 1, 9, 2 ];
let subarrays = [];
subarrays.push([ 1, 2 ]);
subarrays.push([ 1, 3 ]);
subarrays.push([ 1, 4 ]);
subarrays.push([ 3, 4 ]);
document.write(maximumSubarraySum(a, n,subarrays));
</script>
|
Brute Force in python:
Approach:
One simple approach is to generate all possible permutations of the given array and then compute the sum of the subarray for each query. Finally, we can return the maximum sum obtained among all permutations.
the maximum_sum function takes in the input array arr and a list of query tuples queries, where each query tuple represents a range of indices to consider for summing the subarray. The function uses the itertools.permutations method to generate all possible permutations of the input array arr, and for each permutation, it computes the sum of subarrays for all query tuples in queries. The maximum of all such sums is returned as the final output.
Python3
import itertools
def maximum_sum(arr, queries):
max_sum = float ( '-inf' )
for perm in itertools.permutations(arr):
curr_sum = 0
for q in queries:
curr_sum + = sum (perm[q[ 0 ] - 1 :q[ 1 ]])
max_sum = max (max_sum, curr_sum)
return max_sum
arr1 = [ 1 , 1 , 2 , 2 , 4 ]
queries1 = [( 1 , 2 ), ( 2 , 4 ), ( 1 , 3 ), ( 5 , 5 ), ( 3 , 5 )]
print (maximum_sum(arr1, queries1))
arr2 = [ 4 , 1 , 2 , 1 , 9 , 2 ]
queries2 = [( 1 , 2 ), ( 1 , 3 ), ( 1 , 4 ), ( 3 , 4 )]
print (maximum_sum(arr2, queries2))
|
Time Complexity: O(n! * q * n), where n is the length of the array and q is the number of queries.
Space Complexity: O(n! * n)