Open In App

Maximize sum of product of Subsequence sum and its length

Improve
Improve
Like Article
Like
Save
Share
Report

Given an array A[] of length N, the task is to find the maximum sum calculated by multiplying subsequence sum with its length and removing that from the given array until the array is empty.

Examples:

Input: N = 3, A[] = {2, -4, 3}
Output: 6
Explanation: The sub-sequences are chosen as:
First sub-sequence: Chose element A1 and A3 = {2, 3}, Then sum of this operation is: length of subsequence*sum of elements=2 * 5 = 10, now updated A[] is: {-4}
Second subsequence: Only one element is remaining there, So the sub-sequence can be of length one having remaining element= {-4}, The sum of this operation = 1*(-4) = -4
The total sum of all operations= 10 – 4 = 6. It can be verified that this is the maximum possible sum that can be obtained by using the given operation. 

Input: N = 4, A[] = { 4, -1, 2, 3}
Output: 32
Explanation: It will be optimal to take all the elements in one sub-sequence: {4, -1, 2, 3}. The sum of this operation is the length of the sub-sequence*sum of all elements=4 * 8=32. It can be verified that it is the optimal possible maximum sum that we can get.

Approach: Implement the idea below to solve the problem:

The problem can be solved using Greedy approach and can be solved by using the concept of sorting.

Follow the below steps to implement the idea:

  • Create an array (say negatives), for storing negative elements in it.
  • Create variables negativeSum, positiveSum, and positiveCount and initialize all of them equal to 0.
  • Run a loop for traversing over A[] and follow the below-mentioned steps under the scope of the loop:
    • If the current element of A[] is -ve, then add it to negativeSum and add that into negatives array.
    • Otherwise, add it to positiveSum and increment positiveCount.
  • Sort the negatives array in reverse order.
  • Create a variable ans and initialize its value as (positiveSum*positiveCount)+negativeSum.
  • Create a variable let’s say currSum=0.
  • Run a loop from i = 0 to negatives.size() and do the following:
    • Add negatives[i] to currSum.
    • Update ans accordingly as the maximum of [(positiveSum + currSum)*(positiveCount + i+1)+ (negativeSum – currSum)] and existing ans.
  • Return the value of ans as the desired answer.

Below is the implementation of the above approach.

C++




// C++ code to implement the approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Method for printing maximum score that
// can be obtained
long max_score(vector <long> &A)
{
    // List for storing negative elements
    vector <long> negatives;
 
    long negativeSum = 0, positiveCount = 0;
    long positiveSum = 0;
 
    // Loop for traversing over A[]
    for (auto curr : A) {
 
        // Condition when element is negative
        if (curr < 0) {
            negatives.push_back(curr);
            negativeSum += curr;
        }
 
        // Condition when element is positive
        else {
            positiveSum += curr;
            positiveCount++;
        }
    }
 
    // Reversing list of negatives in
    // reversing order
    sort(negatives.begin(), negatives.end(), greater<int>());
 
    // Variable for holding temporary score
    long ans = (positiveSum * positiveCount) + negativeSum;
    long currSum = 0;
 
    // Loop for checking that addition of
    // -ve element in sub-sequence increases
    // score or not For example: {4, 2, 3, -1},
    // We will include all the elements in
    // one sub-sequence
    for (int i = 0; i < negatives.size(); i++) {
        currSum += negatives[i];
        ans = max((positiveSum + currSum) * (positiveCount + i + 1) + (negativeSum - currSum), ans);
    }
 
    return ans;
}
 
int main() {
 
       vector <long> A = { 4, -1, 2, 3 };
       int N = 4;
   
      cout << max_score(A) << endl;
}


Java




// Java code to implement the approach
 
import java.io.*;
import java.lang.*;
import java.util.*;
 
class GFG {
 
    // Driver Code
    public static void main(String[] args)
    {
        long A[] = { 4, -1, 2, 3 };
        int N = 4;
 
        // Function IncompatibleClassChangeError
        System.out.println(max_score(A));
    }
 
    // Method for printing maximum score that
    // can be obtained
    static long max_score(long[] A)
    {
        // List for storing negative elements
        ArrayList<Long> negatives = new ArrayList<>();
 
        long negativeSum = 0, positiveCount = 0;
        long positiveSum = 0;
 
        // Loop for traversing over A[]
        for (long curr : A) {
 
            // Condition when element is negative
            if (curr < 0) {
                negatives.add(curr);
                negativeSum += curr;
            }
 
            // Condition when element is positive
            else {
                positiveSum += curr;
                positiveCount++;
            }
        }
 
        // Reversing list of negatives in
        // reversing order
        Collections.sort(negatives,
                         Collections.reverseOrder());
 
        // Variable for holding temporary score
        long ans
            = (positiveSum * positiveCount) + negativeSum;
        long currSum = 0;
 
        // Loop for checking that addition of
        // -ve element in sub-sequence increases
        // score or not For example: {4, 2, 3, -1},
        // We will include all the elements in
        // one sub-sequence
        for (int i = 0; i < negatives.size(); i++) {
            currSum += negatives.get(i);
            ans = Math.max((positiveSum + currSum)
                                   * (positiveCount + i + 1)
                               + (negativeSum - currSum),
                           ans);
        }
 
        return ans;
    }
}


Python3




# Method for printing maximum score that can be obtained
def max_score(A):
    # List for storing negative elements
    negatives = []
 
    negativeSum = 0
    positiveCount = 0
    positiveSum = 0
 
    # Loop for traversing over A[]
    for curr in A:
        # Condition when element is negative
        if curr < 0:
            negatives.append(curr)
            negativeSum += curr
        # Condition when element is positive
        else:
            positiveSum += curr
            positiveCount += 1
 
    # Reversing list of negatives in
    # reversing order
    negatives.sort(reverse=True)
 
    # Variable for holding temporary score
    ans = (positiveSum * positiveCount) + negativeSum
    currSum = 0
 
    # Loop for checking that addition of
    # -ve element in sub-sequence increases
    # score or not For example: {4, 2, 3, -1},
    # We will include all the elements in
    # one sub-sequence
    for i in range(len(negatives)):
        currSum += negatives[i]
        ans = max((positiveSum + currSum) * (positiveCount + i + 1) + (negativeSum - currSum), ans)
 
    return ans
 
# Driver code
if __name__ == '__main__':
    A = [4, -1, 2, 3]
    print(max_score(A))


C#




// C# code to implement the approach
 
using System;
using System.Collections.Generic;
using System.Linq;
 
class Program {
    // Method for printing maximum score that
    // can be obtained
    static long max_score(List<long> A)
    {
        // List for storing negative elements
        List<long> negatives = new List<long>();
        long negativeSum = 0, positiveCount = 0;
        long positiveSum = 0;
 
        // Loop for traversing over A[]
        foreach(long curr in A)
        {
            // Condition when element is negative
            if (curr < 0) {
                negatives.Add(curr);
                negativeSum += curr;
            }
 
            // Condition when element is positive
            else {
                positiveSum += curr;
                positiveCount++;
            }
        }
 
        // Reversing list of negatives in
        // reversing order
        negatives.Sort();
        negatives.Reverse();
 
        // Variable for holding temporary score
        long ans
            = (positiveSum * positiveCount) + negativeSum;
        long currSum = 0;
 
        // Loop for checking that addition of
        // -ve element in sub-sequence increases
        // score or not For example: {4, 2, 3, -1},
        // We will include all the elements in
        // one sub-sequence
        for (int i = 0; i < negatives.Count(); i++) {
            currSum += negatives[i];
            ans = Math.Max((positiveSum + currSum)
                                   * (positiveCount + i + 1)
                               + (negativeSum - currSum),
                           ans);
        }
 
        return ans;
    }
 
    static void Main(string[] args)
    {
        List<long> A = new List<long>{ 4, -1, 2, 3 };
        int N = 4;
 
        Console.WriteLine(max_score(A));
    }
}


Javascript




// JavaScript code to implement the approach
 
// Method for printing maximum score that can be obtained
function max_score(A) {
    // List for storing negative elements
    let negatives = [];
     
    let negativeSum = 0,
    positiveCount = 0;
    let positiveSum = 0;
     
    // Loop for traversing over A[]
    for (let i = 0; i < A.length; i++) {
        let curr = A[i];
         
        // Condition when element is negative
        if (curr < 0) {
          negatives.push(curr);
          negativeSum += curr;
        }
         
        // Condition when element is positive
        else {
          positiveSum += curr;
          positiveCount++;
        }
    }
     
    // Reversing list of negatives in reversing order
    negatives.sort((a, b) => b - a);
     
    // Variable for holding temporary score
    let ans = positiveSum * positiveCount + negativeSum;
    let currSum = 0;
     
    // Loop for checking that addition of -ve element in sub-sequence increases
    // score or not For example: {4, 2, 3, -1}, We will include all the elements
    // in one sub-sequence
    for (let i = 0; i < negatives.length; i++) {
        currSum += negatives[i];
        ans = Math.max((positiveSum + currSum) * (positiveCount + i + 1) + (negativeSum - currSum), ans);
    }
     
    return ans;
}
 
// Driver Code
let A = [4, -1, 2, 3];
let N = 4;
 
// Function call
console.log(max_score(A));
 
// This code is contributed by sankar.


Output

32

Time Complexity: O(N * log(N))
Auxiliary Space: O(N)

Related Articles:



Last Updated : 17 Mar, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads