Maximizing the sum of subsequence of size at most M
Last Updated :
09 Dec, 2023
Given array A[] of size N, integer M and integer K. The task is to choose at most M elements from the array A[] to form a new array such that if the previous element was chosen is at index i that is A[i] and the current element at index j that is A[j] append A[j] – K * (j – i) to new array. Find the maximum possible sum of elements of the new array.
Note: If no element is chosen before then value of i will be 0 that is A[j] – K * j and it is 1-based indexing.
Examples:
Input: A[] = {3, 2, 5, 4, 6}, M = 2, K = 2
Output: 2
Explanation: It will be optimal to include first and third element of A[] for new array. initially newArray = {} is empty.
- picking first element for new array, previously no element was picked so i = 0 and j = 1 (since we are picking first element) appending A[j] – K * (j – i) = 3 – 2 * (1 – 0) = 1 in new array it becomes newArray = {1}
- picking third element for new array previously we picked element at index i = 1 now we are picking element at index j = 3 so appending A[j] – K * (j – i) = 5 – 2 * (3 – 1) = 5 – 4 = 1 in new array it becomes newArray = {1, 1}
So the sum of newArray will be 2.
Input: A[] = {1, 1, 1, 1}, M = 3, K = 2
Output: 0
Explanation: It will be optimal not to pick any element in this case so sum is zero.
Approach: To solve the problem follow the below idea:
If we include elements i1, i2 ,…, ik from the array A[] the sum will be:
(A[i1] − K * i1) + (A[i2] − K * (i2 − i1)) + … + (A[ik] − K * (ik−ik – 1)) = (A[i1] + A[i2] +…+ A[ik]) − K * ik, by maintaining sum of top M non negative elements using priority queue this problem can be solved.
Below are the steps for the above approach:
- Declare priority queue named ms for tracking first M maximum elements from array.
- Declare currentSum = 0 and ans = 0 for tracking current sum during iterating and final answer of the problem.
- Iterate over N elements
- if A[i] is negative skip the iteration.
- insert A[i] in priority queue
- add A[i] in currentSum
- if size of priority queue is greater than M than delete smallest element from priority queue and subtract that element from currentSum
- Update the answer in ans variable
- return final answer ans.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
#define int long long
int maximizeSum( int A[], int N, int M, int K)
{
multiset< int > ms;
int currentSum = 0, ans = 0;
for ( int i = 0; i < N; i++) {
if (A[i] < 0)
continue ;
ms.insert(A[i]);
currentSum = currentSum + A[i];
if (ms.size() > M) {
currentSum = currentSum - *ms.begin();
ms.erase(ms.begin());
}
ans = max(ans, currentSum - (i + 1) * K);
}
return ans;
}
int32_t main()
{
int M = 2, K = 2;
int A[] = { 3, 2, 5, 4, 6 }, N = 5;
cout << maximizeSum(A, N, M, K) << endl;
int M1 = 3, K1 = 2;
int A1[] = { 1, 1, 1, 1 }, N1 = 4;
cout << maximizeSum(A1, N1, M1, K1) << endl;
return 0;
}
|
Java
import java.util.PriorityQueue;
public class Main {
public static long maximizeSum( int [] A, int N, int M, int K) {
PriorityQueue<Integer> pq = new PriorityQueue<>();
long currentSum = 0 , ans = 0 ;
for ( int i = 0 ; i < N; i++) {
if (A[i] < 0 )
continue ;
pq.offer(A[i]);
currentSum += A[i];
if (pq.size() > M) {
currentSum -= pq.poll();
}
ans = Math.max(ans, currentSum - (i + 1 ) * K);
}
return ans;
}
public static void main(String[] args) {
int M = 2 , K = 2 ;
int [] A = { 3 , 2 , 5 , 4 , 6 };
int N = 5 ;
System.out.println(maximizeSum(A, N, M, K));
int M1 = 3 , K1 = 2 ;
int [] A1 = { 1 , 1 , 1 , 1 };
int N1 = 4 ;
System.out.println(maximizeSum(A1, N1, M1, K1));
}
}
|
Python3
import heapq
def maximize_sum(A, N, M, K):
pq = []
current_sum = 0
ans = 0
for i in range (N):
if A[i] < 0 :
continue
heapq.heappush(pq, A[i])
current_sum + = A[i]
if len (pq) > M:
current_sum - = heapq.heappop(pq)
ans = max (ans, current_sum - (i + 1 ) * K)
return ans
M = 2
K = 2
A = [ 3 , 2 , 5 , 4 , 6 ]
N = 5
print (maximize_sum(A, N, M, K))
M1 = 3
K1 = 2
A1 = [ 1 , 1 , 1 , 1 ]
N1 = 4
print (maximize_sum(A1, N1, M1, K1))
|
C#
using System;
using System.Collections.Generic;
public class Program
{
public static int MaximizeSum( int [] A, int N, int M, int K)
{
SortedSet< int > ss = new SortedSet< int >();
int currentSum = 0, ans = 0;
for ( int i = 0; i < N; i++)
{
if (A[i] < 0)
continue ;
ss.Add(A[i]);
currentSum += A[i];
if (ss.Count > M)
{
currentSum -= ss.Min;
ss.Remove(ss.Min);
}
ans = Math.Max(ans, currentSum - (i + 1) * K);
}
return ans;
}
public static void Main( string [] args)
{
int M = 2, K = 2;
int [] A = { 3, 2, 5, 4, 6 };
int N = 5;
Console.WriteLine(MaximizeSum(A, N, M, K));
int M1 = 3, K1 = 2;
int [] A1 = { 1, 1, 1, 1 };
int N1 = 4;
Console.WriteLine(MaximizeSum(A1, N1, M1, K1));
}
}
|
Javascript
function maximizeSum(A, N, M, K) {
let ms = new Set();
let currentSum = 0;
let ans = 0;
for (let i = 0; i < N; i++) {
if (A[i] < 0)
continue ;
ms.add(A[i]);
currentSum = currentSum + A[i];
if (ms.size > M) {
currentSum = currentSum - Math.min(...ms);
ms. delete (Math.min(...ms));
}
ans = Math.max(ans, currentSum - (i + 1) * K);
}
return ans;
}
let M = 2, K = 2;
let A = [3, 2, 5, 4, 6];
let N = 5;
console.log(maximizeSum(A, N, M, K));
let M1 = 3, K1 = 2;
let A1 = [1, 1, 1, 1];
let N1 = 4;
console.log(maximizeSum(A1, N1, M1, K1));
|
Time Complexity: O(NlogN)
Auxiliary Space: O(N)
Share your thoughts in the comments
Please Login to comment...