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:
#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);
} |
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));
}
} |
# 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))
|
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));
}
} |
// 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)); |
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.