Open In App

Sudo Placement | Placement Tour

Given an array A of N positive integers and a budget B. Your task is to decide the maximum number of elements to be picked from the array such that the cumulative cost of all picked elements is less than or equal to budget B. Cost of picking the ith element is given by : A[i] + (i * K) where, K is a constant whose value is equal to the number of elements picked. The indexing(i) is 1 based. Print the maximum number and its respective cumulative cost.

Examples: 

Input : arr[] = { 2, 3, 5 }, B = 11 
Output : 2 11 
Explanation : Cost of picking maximum elements = {2 + (1 * 2) } + {3 + (2 * 2)} = 4 + 7 = 11 (which is equal to budget)

Input : arr[] = { 1, 2, 5, 6, 3 }, B = 90 
Output : 4 54 

Prerequisites: Binary Search

Approach

The idea here is to use binary search on all possible values of K i.e. the optimal number of elements to be picked. Start with zero as lower bound and End with total number of elements i.e. N as upper bound. Check if by setting K as current Mid, obtained cumulative cost is less than or equal to budget. If it satisfies the condition, then try to increase K by setting Start as (Mid + 1), otherwise try to decrease K by setting End as (Mid – 1)

Checking of the condition can be done in a brute force manner by simply modifying the array according to the given formula and adding the K (current number of elements to be picked) smallest modified values to get the cumulative cost.

Below is the implementation of above approach.  




// CPP Program to find the optimal number of
// elements such that the cumulative value
// should be less than given number
#include <bits/stdc++.h>
 
using namespace std;
 
// This function returns true if the value cumulative
// according to received integer K is less than budget
// B, otherwise returns false
bool canBeOptimalValue(int K, int arr[], int N, int B,
                       int& value)
{
    // Initialize a temporary array which stores
    // the cumulative value of the original array
    int tmp[N];
 
    for (int i = 0; i < N; i++)
        tmp[i] = (arr[i] + K * (i + 1));
 
    // Sort the array to find the smallest K values
    sort(tmp, tmp + N);
 
    value = 0;
    for (int i = 0; i < K; i++)
        value += tmp[i];
 
    // Check if the value is less than budget
    return value <= B;
}
 
// This function prints the optimal number of elements
// and respective cumulative value which is less than
// the given number
void findNoOfElementsandValue(int arr[], int N, int B)
{
    int start = 0; // Min Value or lower bound
 
    int end = N; // Max Value or upper bound
 
    // Initialize answer as zero as optimal value
    // may not exists
    int ans = 0;
 
    int cumulativeValue = 0;
 
    while (start <= end) {
        int mid = (start + end) / 2;
 
        // If the current Mid Value is an optimal
        // value, then try to maximize it
        if (canBeOptimalValue(mid, arr, N, B,
                              cumulativeValue)) {
            ans = mid;
            start = mid + 1;
        }
        else
            end = mid - 1;
    }
    // Call Again to set the corresponding cumulative
    // value for the optimal ans
    canBeOptimalValue(ans, arr, N, B, cumulativeValue);
 
    cout << ans << " " << cumulativeValue << endl;
}
 
// Driver Code
int main()
{
    int arr[] = { 1, 2, 5, 6, 3 };
    int N = sizeof(arr) / sizeof(arr[0]);
 
    // Budget
    int B = 90;
    findNoOfElementsandValue(arr, N, B);
    return 0;
}




// Java Program to find the optimal number of
// elements such that the cumulative value
// should be less than given number
import java.util.*;
 
class GFG
{
    static int value;
 
    // This function returns true if
    // the value cumulative according to
    // received integer K is less than
    // budget B, otherwise returns false
    static boolean canBeOptimalValue(int K, int arr[],
                                     int N, int B)
    {
        // Initialize a temporary array
        // which stores the cumulative value
        // of the original array
        int[] tmp = new int[N];
 
        for (int i = 0; i < N; i++)
            tmp[i] = (arr[i] + K * (i + 1));
 
        // Sort the array to find the
        // smallest K values
        Arrays.sort(tmp);
 
        value = 0;
        for (int i = 0; i < K; i++)
            value += tmp[i];
 
        // Check if the value is less than budget
        return value <= B;
    }
 
    // This function prints the optimal number
    // of elements and respective cumulative value
    // which is less than the given number
    static void findNoOfElementsandValue(int arr[],
                                  int N, int B)
    {
        int start = 0; // Min Value or lower bound
 
        int end = N; // Max Value or upper bound
 
        // Initialize answer as zero as
        // optimal value may not exists
        int ans = 0;
 
        value = 0;
 
        while (start <= end)
        {
            int mid = (start + end) / 2;
 
            // If the current Mid Value is an optimal
            // value, then try to maximize it
            if (canBeOptimalValue(mid, arr, N, B))
            {
                ans = mid;
                start = mid + 1;
            }
            else
                end = mid - 1;
        }
         
        // Call Again to set the corresponding
        // cumulative value for the optimal ans
        canBeOptimalValue(ans, arr, N, B);
 
        System.out.print(ans + " " +
                         value + "\n");
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        int arr[] = { 1, 2, 5, 6, 3 };
        int N = arr.length;
 
        // Budget
        int B = 90;
        findNoOfElementsandValue(arr, N, B);
    }
}
 
// This code is contributed by 29AjayKumar




# Python Program to find the optimal number of
# elements such that the cumulative value
# should be less than given number
value = 0
 
 
# This function returns true if the value cumulative
# according to received integer K is less than budget
# B, otherwise returns false
def canBeOptimalValue(K: int, arr: list, N: int, B: int) -> bool:
    global value
 
    # Initialize a temporary array which stores
    # the cumulative value of the original array
    tmp = [0] * N
 
    for i in range(N):
        tmp[i] = (arr[i] + K * (i + 1))
 
    # Sort the array to find the smallest K values
    tmp.sort()
 
    value = 0
    for i in range(K):
        value += tmp[i]
 
    # Check if the value is less than budget
    return value <= B
 
# This function prints the optimal number of elements
# and respective cumulative value which is less than
# the given number
def findNoOfElementsandValue(arr: list, N: int, B: int):
    global value
    start = 0 # Min Value or lower bound
 
    end = N # Max Value or upper bound
 
    # Initialize answer as zero as optimal value
    # may not exists
    ans = 0
 
    value = 0
    while start <= end:
        mid = (start + end) // 2
 
        # If the current Mid Value is an optimal
        # value, then try to maximize it
        if canBeOptimalValue(mid, arr, N, B):
            ans = mid
            start = mid + 1
        else:
            end = mid - 1
 
    # Call Again to set the corresponding cumulative
    # value for the optimal ans
    canBeOptimalValue(ans, arr, N, B)
 
    print(ans, value)
 
# Driver Code
if __name__ == "__main__":
 
    arr = [1, 2, 5, 6, 3]
    N = len(arr)
 
    # Budget
    B = 90
    findNoOfElementsandValue(arr, N, B)
 
# This code is contributed by
# sanjeev2552




// C# Program to find the optimal number of
// elements such that the cumulative value
// should be less than given number
using System;
 
class GFG
{
    static int value;
 
    // This function returns true if
    // the value cumulative according to
    // received integer K is less than
    // budget B, otherwise returns false
    static bool canBeOptimalValue(int K, int []arr,
                                  int N, int B)
    {
        // Initialize a temporary array
        // which stores the cumulative value
        // of the original array
        int[] tmp = new int[N];
 
        for (int i = 0; i < N; i++)
            tmp[i] = (arr[i] + K * (i + 1));
 
        // Sort the array to find the
        // smallest K values
        Array.Sort(tmp);
 
        value = 0;
        for (int i = 0; i < K; i++)
            value += tmp[i];
 
        // Check if the value is less than budget
        return value <= B;
    }
 
    // This function prints the optimal number
    // of elements and respective cumulative value
    // which is less than the given number
    static void findNoOfElementsandValue(int []arr,
                                  int N, int B)
    {
        int start = 0; // Min Value or lower bound
 
        int end = N; // Max Value or upper bound
 
        // Initialize answer as zero as
        // optimal value may not exists
        int ans = 0;
 
        value = 0;
 
        while (start <= end)
        {
            int mid = (start + end) / 2;
 
            // If the current Mid Value is an optimal
            // value, then try to maximize it
            if (canBeOptimalValue(mid, arr, N, B))
            {
                ans = mid;
                start = mid + 1;
            }
            else
                end = mid - 1;
        }
         
        // Call Again to set the corresponding
        // cumulative value for the optimal ans
        canBeOptimalValue(ans, arr, N, B);
 
        Console.Write(ans + " " +
                    value + "\n");
    }
 
    // Driver Code
    public static void Main(String[] args)
    {
        int []arr = { 1, 2, 5, 6, 3 };
        int N = arr.Length;
 
        // Budget
        int B = 90;
        findNoOfElementsandValue(arr, N, B);
    }
}
 
// This code is contributed by Rajput-Ji




<script>
 
// JavaScript Program to find the optimal number of
// elements such that the cumulative value
// should be less than given number
 
 
// This function returns true if the value cumulative
// according to received integer K is less than budget
// B, otherwise returns false
 
let cumulativeValue = 0;
 
function canBeOptimalValue(K, arr, N, B) {
    // Initialize a temporary array which stores
    // the cumulative value of the original array
    let tmp = new Array(N);
 
    for (let i = 0; i < N; i++)
        tmp[i] = (arr[i] + K * (i + 1));
 
    // Sort the array to find the smallest K values
    tmp.sort((a, b) => a - b);
 
    cumulativeValue = 0;
    for (let i = 0; i < K; i++)
        cumulativeValue += tmp[i];
 
    // Check if the value is less than budget
    return cumulativeValue <= B;
}
 
// This function prints the optimal number of elements
// and respective cumulative value which is less than
// the given number
function findNoOfElementsandValue(arr, N, B) {
    let start = 0; // Min Value or lower bound
 
    let end = N; // Max Value or upper bound
 
    // Initialize answer as zero as optimal value
    // may not exists
    let ans = 0;
 
 
 
    while (start <= end) {
        let mid = Math.floor((start + end) / 2);
 
        // If the current Mid Value is an optimal
        // value, then try to maximize it
        if (canBeOptimalValue(mid, arr, N, B)) {
            ans = mid;
            start = mid + 1;
        }
        else
            end = mid - 1;
    }
    // Call Again to set the corresponding cumulative
    // value for the optimal ans
    canBeOptimalValue(ans, arr, N, B, cumulativeValue);
 
    document.write(ans + " " + cumulativeValue + "<br>");
}
 
// Driver Code
 
let arr = [1, 2, 5, 6, 3];
let N = arr.length;
 
// Budget
let B = 90;
findNoOfElementsandValue(arr, N, B);
 
</script>

Output
4 54

Time Complexity: O(N * (log N)2), where N is the number of elements in the given array.


Article Tags :