Perform K of Q queries to maximize the sum of the array elements
Last Updated :
28 Feb, 2023
Given an array arr[] of N integers and an integer K. Also given are Q queries which have two numbers L and R. For every query, you can increase all the elements of the array in the index range [L, R] by 1. The task is to choose exactly K queries out of Q queries such that the sum of the array at the end is maximized. Print the sum after performing K such queries.
Examples:
Input: arr[] = {1, 1, 2, 2, 2, 3},
que[] = {{0, 4}, {1, 2}, {2, 5}, {2, 3}, {2, 4}},
K = 3
Output: 23
We choose the first, third and the fifth query.
After performing first query -> arr[] = {2, 2, 3, 3, 3, 3}
After performing third query -> arr[] = {2, 2, 4, 4, 4, 4}
After performing fifth query -> arr[] = {2, 2, 5, 5, 5, 4}
And the array sum is 2 + 2 + 5 + 5 + 5 + 4 = 23.
Input: arr[] = {4, 5, 4, 21, 22},
que[] = {{1, 2}, {2, 2}, {2, 4}, {2, 2}},
K = 2
Output: 61
Naive approach: A naive approach is to use Dynamic Programming and Combinatorics, in which we choose any K queries out of Q. The combination which gives the maximum sum of the array will be the answer.
Time Complexity: O(N*N*K), as we will use recursion with memorization.
Auxiliary Space: O(N*N*K), as we will be using extra space for the memorization.
Efficient Approach: Since we need to maximize the sum of the array at the end. We just need to choose those queries that affect the maximum number of elements from the array i.e. with bigger ranges. Every query contributes (R – L + 1) to the increase in the sum if it is chosen. The sum of the array elements after performing such queries will be (initial sum of the array + (Contribution of K queries)).
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int getFinalSum( int a[], int n, pair< int , int > queries[],
int q, int k)
{
int answer = 0;
for ( int i = 0; i < n; i++)
answer += a[i];
vector< int > contribution;
for ( int i = 0; i < q; i++) {
contribution.push_back(queries[i].second
- queries[i].first + 1);
}
sort(contribution.begin(), contribution.end(),
greater< int >());
int i = 0;
while (i < k) {
answer += contribution[i];
i++;
}
return answer;
}
int main()
{
int a[] = { 1, 1, 2, 2, 2, 3 };
int n = sizeof (a) / sizeof (a[0]);
pair< int , int > queries[] = { { 0, 4 },
{ 1, 2 },
{ 2, 5 },
{ 2, 3 },
{ 2, 4 } };
int q = sizeof (queries) / sizeof (queries[0]);
int k = 3;
cout << getFinalSum(a, n, queries, q, k);
return 0;
}
|
Java
import java.util.*;
class GFG
{
static class pair
{
int first,second;
pair( int f, int s)
{
first = f;
second = s;
}
}
static int getFinalSum( int a[], int n, pair queries[],
int q, int k)
{
int answer = 0 ;
for ( int i = 0 ; i < n; i++)
answer += a[i];
Vector<Integer> contribution = new Vector<Integer>();
for ( int i = 0 ; i < q; i++)
{
contribution.add(queries[i].second
- queries[i].first + 1 );
}
Comparator<Integer> Comp = new Comparator<Integer>()
{
public int compare(Integer e1,Integer e2)
{
if (e1 > e2)
return - 1 ;
else
return 1 ;
}
};
Collections.sort(contribution,Comp);
int i = 0 ;
while (i < k)
{
answer += ( int ) contribution.get(i);
i++;
}
return answer;
}
public static void main(String args[])
{
int a[] = { 1 , 1 , 2 , 2 , 2 , 3 };
int n = a.length;
pair queries[] = new pair[ 5 ];
queries[ 0 ] = new pair( 0 , 4 );
queries[ 1 ] = new pair( 1 , 2 );
queries[ 2 ] = new pair( 2 , 5 );
queries[ 3 ] = new pair( 2 , 3 );
queries[ 4 ] = new pair( 2 , 4 );
int q = queries.length;
int k = 3 ;
System.out.println( getFinalSum(a, n, queries, q, k));
}
}
|
Python3
def getFinalSum(a, n, queries, q, k):
answer = 0
for i in range (n):
answer + = a[i]
contribution = []
for i in range (q):
contribution.append(queries[i][ 1 ] -
queries[i][ 0 ] + 1 )
contribution.sort(reverse = True )
i = 0
while (i < k):
answer + = contribution[i]
i + = 1
return answer
if __name__ = = '__main__' :
a = [ 1 , 1 , 2 , 2 , 2 , 3 ]
n = len (a)
queries = [[ 0 , 4 ], [ 1 , 2 ],
[ 2 , 5 ], [ 2 , 3 ],
[ 2 , 4 ]]
q = len (queries);
k = 3
print (getFinalSum(a, n, queries, q, k))
|
C#
using System;
using System.Collections;
using System.Collections.Generic;
public class GFG
{
public class pair
{
public int first, second;
public pair( int f, int s)
{
first = f;
second = s;
}
}
public static int getFinalSum( int [] a, int n, pair[] queries, int q, int k)
{
int answer = 0;
for ( int i = 0; i < n; i++)
answer += a[i];
List< int > contribution = new List< int >();
for ( int i = 0; i < q; i++)
{
contribution.Add(queries[i].second
- queries[i].first + 1);
}
contribution.Sort();
contribution.Reverse();
int j = 0;
while (j < k)
{
answer += contribution[j];
j++;
}
return answer;
}
public static void Main(String[] args)
{
int [] a = { 1, 1, 2, 2, 2, 3 };
int n = a.Length;
pair[] queries = new pair[5];
queries[0] = new pair(0, 4);
queries[1] = new pair(1, 2);
queries[2] = new pair(2, 5);
queries[3] = new pair(2, 3);
queries[4] = new pair(2, 4);
int q = queries.Length;
int k = 3;
Console.WriteLine(getFinalSum(a, n, queries, q, k));
}
}
|
Javascript
<script>
const getFinalSum = (a, n, queries, q, k) => {
let answer = 0;
for (let i = 0; i < n; i++)
answer += a[i];
let contribution = [];
for (let i = 0; i < q; i++) {
contribution.push(queries[i][1] - queries[i][0] + 1);
}
contribution.sort((a, b) => b - a);
let i = 0;
while (i < k) {
answer += contribution[i];
i++;
}
return answer;
}
const a = [1, 1, 2, 2, 2, 3];
const n = a.length;
const queries = [
[0, 4],
[1, 2],
[2, 5],
[2, 3],
[2, 4]
];
const q = queries.length;
let k = 3;
document.write(getFinalSum(a, n, queries, q, k));
</script>
|
Time Complexity: O(max(n,k,q*log(q))), as we are using a loop to traverse n and k times and we are using a sort function to sort an array of size q.
Auxiliary Space: O(q), as we are using extra space for the array contribution.
Share your thoughts in the comments
Please Login to comment...