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> |
4 54
Time Complexity: O(N * (log N)2), where N is the number of elements in the given array.