Open In App

Best order to maximise the value

Improve
Improve
Like Article
Like
Save
Share
Report

Given, an array arr[] of N integers, the task is to select some integers from this array arr[] and arrange them in another array brr[], such that the sum of brr[i]*(i+1) for every index in array brr is maximum. Find out the maximum possible such value for a given array arr.

Input: N = 5, arr[] = {-1, -8, 0, 5, -9}
Output: 14
Explanation: By selecting -1, 0, and 5 we will get the maximum possible value.(-1*1 + 0*2 + 5*3 = 14)

Input: N = 3, arr[] = {-1, -8, -9}
Output: 0
Explanation: Since all the numbers are negative it’s better not to select any number.

Approach: To solve the problem follow the below idea:

The problem can be solved using a greedy approach. The intuition behind the greedy approach is that the maximum value is obtained by selecting the largest number first, and the smallest number last. By sorting the array in decreasing order, we can ensure that we have the largest number at first, and thus maximize the value.

Steps that were to follow the above approach:

  • First, we sort the input array in decreasing order. 
  • Then, we iterate over the array and calculate the prefix sums of the elements, adding each prefix sum to the result as long as it remains non-negative. 
  • If the prefix sum becomes negative at any point, we stop the iteration and return the current result.
  • By stopping the iteration as soon as the prefix sum becomes negative, we can ensure that we don’t select any numbers that have a net negative contribution to the total value. This allows us to obtain the maximum value.

Below is the code to implement the above approach:

C++




#include <bits/stdc++.h>
using namespace std;
 
// Function to return best possible value
int bestOrder(int arr[], int N)
{
 
    // Sorting the array in
    // decreasing order
    sort(arr, arr + N, greater<int>());
 
    // Initialising the prefixsum and
    // result to zero
    int prefixsum = 0, result = 0;
 
    // Iterating over the sorted array
    // from the beginning
    for (int i = 0; i < N; i++) {
 
        // Computing the prefix sum
        prefixsum += arr[i];
 
        // if prefisum < 0 then we no longer
        // need to select the numbers
        if (prefixsum < 0)
            break;
 
        // Summing prefixsum to the result,
        // this will ensure brr[i] * (i + 1)
        result += prefixsum;
    }
    return result;
}
 
int main()
{
    int N = 5;
    int arr[] = { -1, -8, 0, 5, -9 };
 
    // Printing the best possible result
    cout << bestOrder(arr, N);
}


Java




import java.util.Arrays;
 
public class GFG {
 
    // Function to return the best possible value
    static int bestOrder(int[] arr, int N) {
 
        // Sorting the array in decreasing order
        Arrays.sort(arr);
        for (int i = 0, j = N - 1; i < j; i++, j--) {
            int temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
        }
 
        // Initializing the prefixsum and result to zero
        int prefixsum = 0, result = 0;
 
        // Iterating over the sorted array from the beginning
        for (int i = 0; i < N; i++) {
 
            // Computing the prefix sum
            prefixsum += arr[i];
 
            // If prefixsum < 0, then we no longer need to select the numbers
            if (prefixsum < 0)
                break;
 
            // Summing prefixsum to the result, this will ensure brr[i] * (i + 1)
            result += prefixsum;
        }
        return result;
    }
 
    public static void main(String[] args) {
        int N = 5;
        int[] arr = { -1, -8, 0, 5, -9 };
 
        // Printing the best possible result
        System.out.println(bestOrder(arr, N));
    }
}


Python3




# Function at return best possible value
def bestOrder(arr, N):
 
        # Sorting the array in
    # decreasing order
    arr.sort(reverse = True)
 
    # Initialising the prefixsum and
    # result to zero
    prefixsum, result = 0, 0
 
    # Iterating over the sorted array
    # from the beginning
    for i in range(N):
 
      # Computing the prefix sum
        prefixsum += arr[i]
 
      # if prefisum < 0 then we no longer
      # need to select the  numbers
        if prefixsum < 0:
            break
      # Summing prefixsum to the result,
      # this will ensure brr[i] * (i + 1)
        result += prefixsum
    return result
 
 
N = 5
arr = [-1, -8, 0, 5, -9]
 
# Printing the best possible result
print(bestOrder(arr, N))


C#




using System;
using System.Linq;
 
class Program
{
    // Function to return best possible value
    static int BestOrder(int[] arr, int N)
    {
        // Sorting the array in
        // decreasing order
        Array.Sort(arr, (x, y) => y.CompareTo(x));
        // Initialising the prefixsum and
        // result to zero
        int prefixsum = 0, result = 0;
        // Iterating over the sorted array
        // from the beginning
        for (int i = 0; i < N; i++)
        {
            // Computing the prefix sum
            prefixsum += arr[i];
            // if prefisum < 0 then we no longer
            // need to select the numbers
            if (prefixsum < 0)
                break;
            // Summing prefixsum to the result,
            // this will ensure brr[i] * (i + 1)
            result += prefixsum;
        }
        return result;
    }
    static void Main(string[] args)
    {
        int N = 5;
        int[] arr = { -1, -8, 0, 5, -9 };
        // Printing the best possible result
        Console.WriteLine(BestOrder(arr, N));
    }
}


Javascript




// Function to return best possible value
function bestOrder(arr, N) {
    // Sorting the array in
    // decreasing order
    arr.sort((a, b) => b - a);
    // Initialising the prefixsum and
    // result to zero
    let prefixsum = 0, result = 0;
    // Iterating over the sorted array
    // from the beginning
    for (let i = 0; i < N; i++) {
        // Computing the prefix sum
        prefixsum += arr[i];
        // if prefisum < 0 then we no longer
        // need to select the numbers
        if (prefixsum < 0)
            break;
        // Summing prefixsum to the result,
        // this will ensure brr[i] * (i + 1)
        result += prefixsum;
    }
    return result;
}
const N = 5;
const arr = [ -1, -8, 0, 5, -9 ];
// Printing the best possible result
console.log(bestOrder(arr, N));


Output

14





Time Complexity: O(N*logN), where N is the length of the array.
Auxiliary Space: O(1), as we are not using any extra space.



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