Maximum sum with limited queries
Last Updated :
29 Oct, 2023
Given an array arr[] of n integers in sorted order, find the maximum number of largest elements that can be selected from the array such that the sum is less than or equal to k. You can select an element any number of times. The sum of the selected elements should be maximized. You can query the value of any element at most 50 times. If you exceed this limit, you cannot select any element. Assume that there is an infinite supply of elements available and the values of elements are pairwise distinct.
Examples:
Input: n = 3, k = 5, arr[] = {2, 4, 6}
Output: 1
Explanation: The elements are [2, 4, 6] and the value of k is 5. So, we can pick only 1 element that is 4 (since we always picks the largest one).
Input: n = 4, k = 9, arr[] = {1, 2, 3, 4}
Output: 3
Explanation: The elements are [1, 2, 3, 4] and the value of k is 9. So we can pick element 4, 2 times and element 1, 1 time.
Approach: To solve the problem follow the below idea:
As the elements are arranged in sorted order, binary search must be used to discover the solution and we can use the get() function only 50 times.
Below are the steps for the above approach:
- Initializes a variable count = 0 and a map hm to store the results of the binary search for each element.
- Run a loop until k is 0 or all elements in the array have been searched.
- Initialize low = 0 and high = n-1 and search for the largest element in the Element array that is less than or equal to k.
- If the binary search finds an element less than or equal to k, update low = mid+1, else update high = mid -1 to continue the search for the next smallest element.
- Check if high == 1, and break the loop.
- Calculate the number of times the largest element less than or equal to k appears in the Element array, and add this value to the count variable, count += (k / hm.get(high)).
- Subtract the total value of the largest element less than or equal to k from k, k -= (k / hm.get(high)) * hm.get(high).
- The loop is repeated with the new value of k.
- Return the value of the count.
Below is the code for the above approach:
C++
#include <iostream>
#include <unordered_map>
using namespace std;
class Element {
private :
int * arr;
public :
Element( int * arr) {
this ->arr = arr;
}
long Get( int i) {
return arr[i];
}
};
class GFG {
private :
static Element* element;
public :
GFG(Element* element) {
GFG::element = element;
}
static long Find( int n, long k) {
int low = 0, high = n - 1;
int count = 0;
unordered_map< int , long > hm;
while (k > 0) {
low = 0;
while (low <= high) {
int mid = (low + high) / 2;
long temp;
if (hm.find(mid) == hm.end())
temp = element->Get(mid);
else
temp = hm[mid];
hm[mid] = temp;
if (temp <= k)
low = mid + 1;
else
high = mid - 1;
}
if (high == -1)
break ;
count += ( int )(k / hm[high]);
k -= (k / hm[high]) * hm[high];
}
return count;
}
};
Element* GFG::element;
int main() {
int n = 3;
long k = 5;
int arr[] = { 2, 4, 6 };
Element* element = new Element(arr);
GFG* gfg = new GFG(element);
cout << GFG::Find(n, k) << endl;
return 0;
}
|
Java
import java.util.*;
class Element {
int [] arr;
public Element( int [] arr) { this .arr = arr; }
public long get( int i) { return arr[i]; }
}
class GFG {
static Element element;
GFG(Element element) { this .element = element; }
static long find( int n, long k)
{
int low = 0 , high = n - 1 ;
int count = 0 ;
Map<Integer, Long> hm = new HashMap<>();
while (k > 0 ) {
low = 0 ;
while (low <= high) {
int mid = (low + high) / 2 ;
long temp;
if (!hm.containsKey(mid))
temp = element.get(mid);
else
temp = hm.get(mid);
hm.put(mid, temp);
if (temp <= k)
low = mid + 1 ;
else
high = mid - 1 ;
}
if (high == - 1 )
break ;
count += (k / hm.get(high));
k -= (k / hm.get(high)) * hm.get(high);
}
return count;
}
public static void main(String[] args)
{
int n = 3 ;
long k = 5 ;
int [] arr = { 2 , 4 , 6 };
element = new Element(arr);
System.out.println(find(n, k));
}
}
|
Python3
class Element:
def __init__( self , arr):
self .arr = arr
def Get( self , i):
return self .arr[i]
class GFG:
element = None
def __init__( self , element):
GFG.element = element
@staticmethod
def Find(n, k):
low = 0
high = n - 1
count = 0
hm = {}
while k > 0 :
low = 0
while low < = high:
mid = (low + high) / / 2
temp = GFG.element.Get(mid) if mid not in hm else hm[mid]
hm[mid] = temp
if temp < = k:
low = mid + 1
else :
high = mid - 1
if high = = - 1 :
break
count + = k / / hm[high]
k - = (k / / hm[high]) * hm[high]
return count
n = 3
k = 5
arr = [ 2 , 4 , 6 ]
element = Element(arr)
gfg = GFG(element)
print (GFG.Find(n, k))
|
C#
using System;
using System.Collections.Generic;
public class Element
{
private int [] arr;
public Element( int [] arr)
{
this .arr = arr;
}
public long Get( int i)
{
return arr[i];
}
}
public class GFG
{
private static Element element;
public GFG(Element element)
{
GFG.element = element;
}
public static long Find( int n, long k)
{
int low = 0, high = n - 1;
int count = 0;
Dictionary< int , long > hm = new Dictionary< int , long >();
while (k > 0)
{
low = 0;
while (low <= high)
{
int mid = (low + high) / 2;
long temp;
if (!hm.ContainsKey(mid))
temp = element.Get(mid);
else
temp = hm[mid];
hm[mid] = temp;
if (temp <= k)
low = mid + 1;
else
high = mid - 1;
}
if (high == -1)
break ;
count += ( int )(k / hm[high]);
k -= (k / hm[high]) * hm[high];
}
return count;
}
public static void Main( string [] args)
{
int n = 3;
long k = 5;
int [] arr = { 2, 4, 6 };
element = new Element(arr);
Console.WriteLine(Find(n, k));
}
}
|
Javascript
class Element {
constructor(arr) {
this .arr = arr;
}
get(i) {
return this .arr[i];
}
}
let element;
function find(n, k) {
let low = 0,
high = n - 1;
let count = 0;
let hm = new Map();
while (k > 0) {
low = 0;
while (low <= high) {
let mid = Math.floor((low + high) / 2);
let temp;
if (!hm.has(mid)) temp = element.get(mid);
else temp = hm.get(mid);
hm.set(mid, temp);
if (temp <= k) low = mid + 1;
else high = mid - 1;
}
if (high == -1) break ;
count += Math.floor(k / hm.get(high));
k -= Math.floor(k / hm.get(high)) * hm.get(high);
}
return count;
}
let n = 3;
let k = 5;
let arr = [2, 4, 6];
element = new Element(arr);
console.log( "The number of ways are: " + find(n, k));
|
Time Complexity: O(logN)
Auxiliary Space: O(logN)
Share your thoughts in the comments
Please Login to comment...