Maximum consecutive elements that can be purchased under given budget
Last Updated :
24 Apr, 2023
Given N elements that have two costs associated with them that are represented in two arrays Costs1[] and Costs2[] of length N each and an integer budget. The task is to find the maximum number of consecutive elements that can be bought when the cost of buying k consecutive elements is calculated as max(costs1) + k*sum(costs2), where max(costs1) is the max of Costs1[] among the k elements and sum(costs2) is the sum of Costs2[] of the selected k elements.
Examples:
Input: Costs1[] = {3, 6, 1, 3, 4}, Costs2[] = {2, 1, 3, 4, 5}, budget = 25
Output: 3
Explanation: Consider the first 3 elements.
The total cost will be max(3, 6, 1) + 3 * sum(2, 1, 3) = 6 + 3 * 6 = 24 which is less than 25.
It can be shown that it is not possible to select more than 3 consecutive elements within budget.
Input: Costs1[] = {12, 13, 19}, Costs2[] = {9, 7, 6}, budget = 18
Output: 0
Explanation: No element can be bought that does not exceed the budget, so we return 0.
Approach: To solve the problem follow the below idea:
Use sliding window technique to get the value for subarray [start, end]. If value exceeds budget move start and remove values associated with start to get new value and each time take maximum of the answer and length of the subarray.
Follow these steps to solve the problem:
- Take two pointers i and j for the start and end of the window, initialize both with 0, and a multiset for keeping the track of maximum among Costs1[].
- Include the jth elements and add Costs2[j] to runningCost and insert Costs1[j] to multiset.
- Calculate the total cost of the current window by adding the maximum among Costs1[] from the multiset and runningCost of the window.
- If the cost is greater than the budget then remove the ith element from the start of the window and update runningCost by subtracting Costs2[i].
- Also, remove the occurrence of the Costs1[i] from the multiset to maintain the current maximum in that window.
- Else if runningCost is less than or equal to the budget then it’s a valid window. So update the answer with the maximum of answer and length of the current window (j – i + 1).
- Return the answer when the loop ends.
Below is the implementation of the above approach.
C++
#include <bits/stdc++.h>
using namespace std;
int maximumObjects(vector< int >& Costs1, vector< int >& Costs2,
int budget)
{
int n = Costs1.size();
int totalCost = 0, runningCost = 0;
int i = 0, j = 0, ans = 0;
multiset< int > ms;
while (j < n) {
ms.insert(Costs1[j]);
runningCost += Costs2[j];
totalCost
= *ms.rbegin() + (j - i + 1) * runningCost;
if (totalCost > budget) {
runningCost -= Costs2[i];
ms.erase(ms.find(Costs1[i]));
i++;
}
else
ans = max(ans, j - i + 1);
j++;
}
return ans;
}
int main()
{
vector< int > Costs1 = { 3, 6, 1, 3, 4 };
vector< int > Costs2 = { 2, 1, 3, 4, 5 };
int budget = 25;
cout << maximumObjects(Costs1, Costs2, budget);
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class GFG {
public static int maximumObjects(List<Integer> Costs1,
List<Integer> Costs2,
int budget)
{
int n = Costs1.size();
int totalCost = 0 , runningCost = 0 ;
int i = 0 , j = 0 , ans = 0 ;
TreeSet<Integer> ms = new TreeSet<>();
while (j < n) {
ms.add(Costs1.get(j));
runningCost += Costs2.get(j);
totalCost
= ms.last() + (j - i + 1 ) * runningCost;
if (totalCost > budget) {
runningCost -= Costs2.get(i);
ms.remove(Costs1.get(i));
i++;
}
else
ans = Math.max(ans, j - i + 1 );
j++;
}
return ans;
}
public static void main(String[] args)
{
List<Integer> Costs1 = new ArrayList<>();
Costs1.add( 3 );
Costs1.add( 6 );
Costs1.add( 1 );
Costs1.add( 3 );
Costs1.add( 4 );
List<Integer> Costs2 = new ArrayList<>();
Costs2.add( 2 );
Costs2.add( 1 );
Costs2.add( 3 );
Costs2.add( 4 );
Costs2.add( 5 );
int budget = 25 ;
System.out.println(
maximumObjects(Costs1, Costs2, budget));
}
}
|
Python3
def maximumObjects(Costs1, Costs2, budget):
n = len (Costs1)
totalCost = 0
runningCost = 0
i, j, ans = 0 , 0 , 0
ms = set ()
while (j < n):
ms.add(Costs1[j])
runningCost = runningCost + Costs2[j]
totalCost = next ( iter (ms)) + (j - i + 1 ) * runningCost
if (totalCost > budget):
runningCost = runningCost - Costs2[i]
ms.remove(Costs1[i])
i = i + 1
else :
ans = max (ans, j - i + 1 )
j = j + 1
return ans
Costs1 = [ 3 , 6 , 1 , 3 , 4 ]
Costs2 = [ 2 , 1 , 3 , 4 , 5 ]
budget = 25
print (maximumObjects(Costs1, Costs2, budget))
|
C#
using System;
using System.Collections.Generic;
public class GFG {
public static int maximumObjects(List< int > Costs1,
List< int > Costs2,
int budget)
{
int n = Costs1.Count;
int totalCost = 0, runningCost = 0;
int i = 0, j = 0, ans = 0;
SortedSet< int > ms = new SortedSet< int >();
while (j < n) {
ms.Add(Costs1[j]);
runningCost += Costs2[j];
totalCost = ms.Max + (j - i + 1) * runningCost;
if (totalCost > budget) {
runningCost -= Costs2[i];
ms.Remove(Costs1[i]);
i++;
}
else
ans = Math.Max(ans, j - i + 1);
j++;
}
return ans;
}
static public void Main()
{
List< int > Costs1 = new List< int >();
Costs1.Add(3);
Costs1.Add(6);
Costs1.Add(1);
Costs1.Add(3);
Costs1.Add(4);
List< int > Costs2 = new List< int >();
Costs2.Add(2);
Costs2.Add(1);
Costs2.Add(3);
Costs2.Add(4);
Costs2.Add(5);
int budget = 25;
Console.WriteLine(
maximumObjects(Costs1, Costs2, budget));
}
}
|
Javascript
const maximumObjects = (Costs1, Costs2, budget) => {
let n = Costs1.length;
let totalCost = 0, runningCost = 0;
let i = 0, j = 0, ans = 0;
let ms = new Set();
while (j < n) {
ms.add(Costs1[j]);
runningCost += Costs2[j];
totalCost = ms.values().next().value + (j - i + 1) * runningCost;
if (totalCost > budget) {
runningCost -= Costs2[i];
if (ms.has(Costs1[i]))
ms. delete (Costs1[i]);
i++;
}
else
ans = Math.max(ans, j - i + 1);
j++;
}
return ans;
}
let Costs1 = [3, 6, 1, 3, 4];
let Costs2 = [2, 1, 3, 4, 5];
let budget = 25;
console.log(maximumObjects(Costs1, Costs2, budget));
|
PHP
<?php
function maximumObjects( $Costs1 , $Costs2 , $budget )
{
$n = count ( $Costs1 );
$totalCost = 0;
$runningCost = 0;
$i = 0;
$j = 0;
$ans = 0;
$ms = array ();
while ( $j < $n )
{
array_push ( $ms , $Costs1 [ $j ]);
$runningCost += $Costs2 [ $j ];
$totalCost = max( $ms ) + ( $j - $i + 1) * $runningCost ;
if ( $totalCost > $budget )
{
$runningCost -= $Costs2 [ $i ];
unset( $ms [ array_search ( $Costs1 [ $i ], $ms )]);
$i ++;
}
else
$ans = max( $ans , $j - $i + 1);
$j ++;
}
return $ans ;
}
$Costs1 = array (3, 6, 1, 3, 4);
$Costs2 = array (2, 1, 3, 4, 5);
$budget = 25;
echo maximumObjects( $Costs1 , $Costs2 , $budget );
?>
|
Time Complexity: O(N * log N)
Auxiliary Space: O(N)
Another Approach:
- Take two pointers i and j for the start and end of the window, initialize both with 0, and a deque for keeping the track of maximum among Costs1[].
- Include the jth element and add Costs2[j] to runningCost and insert Costs1[j] to the back of the deque.
- Remove all elements from the front of the deque until the current maximum among Costs1[] is at the front of the deque.
- Calculate the total cost of the current window by adding the maximum among Costs1[] from the front of the deque and runningCost of the window.
- If the cost is greater than the budget then remove the ith element from the start of the window and update runningCost by subtracting Costs2[i].
- Also, remove the front element from the deque if it is equal to Costs1[i] to maintain the current maximum in that window.
- Else if runningCost is less than or equal to the budget then it’s a valid window. So update the answer with the maximum of answer and length of the current window (j – i + 1).
- Return the answer when the loop ends.
C++
#include <bits/stdc++.h>
using namespace std;
int maximumObjects(vector< int >& Costs1, vector< int >& Costs2,
int budget)
{
int n = Costs1.size();
int totalCost = 0, runningCost = 0;
int i = 0, j = 0, ans = 0;
deque< int > dq;
while (j < n) {
while (!dq.empty() && Costs1[j] >= dq.back())
dq.pop_back();
dq.push_back(Costs1[j]);
runningCost += Costs2[j];
totalCost = dq.front() + (j - i + 1) * runningCost;
if (totalCost > budget) {
runningCost -= Costs2[i];
if (dq.front() == Costs1[i])
dq.pop_front();
i++;
}
else
ans = max(ans, j - i + 1);
j++;
}
return ans;
}
int main()
{
vector< int > Costs1 = { 3, 6, 1, 3, 4 };
vector< int > Costs2 = { 2, 1, 3, 4, 5 };
int budget = 25;
cout << maximumObjects(Costs1, Costs2, budget);
return 0;
}
|
Java
import java.util.*;
public class Main {
static int maximumObjects(List<Integer> Costs1,
List<Integer> Costs2,
int budget)
{
int n = Costs1.size();
int totalCost = 0 , runningCost = 0 ;
int i = 0 , j = 0 , ans = 0 ;
Deque<Integer> dq = new LinkedList<>();
while (j < n) {
while (!dq.isEmpty()
&& Costs1.get(j) >= dq.peekLast())
dq.removeLast();
dq.addLast(Costs1.get(j));
runningCost += Costs2.get(j);
totalCost = dq.peekFirst()
+ (j - i + 1 ) * runningCost;
if (totalCost > budget) {
runningCost -= Costs2.get(i);
if (dq.peekFirst() == Costs1.get(i))
dq.removeFirst();
i++;
}
else
ans = Math.max(ans, j - i + 1 );
j++;
}
return ans;
}
public static void main(String[] args)
{
List<Integer> Costs1 = Arrays.asList( 3 , 6 , 1 , 3 , 4 );
List<Integer> Costs2 = Arrays.asList( 2 , 1 , 3 , 4 , 5 );
int budget = 25 ;
System.out.println(
maximumObjects(Costs1, Costs2, budget));
}
}
|
Python3
from collections import deque
def maximum_objects(Costs1, Costs2, budget):
n = len (Costs1)
total_cost = 0
running_cost = 0
i = 0
j = 0
ans = 0
dq = deque()
while j < n:
while dq and Costs1[j] > = dq[ - 1 ]:
dq.pop()
dq.append(Costs1[j])
running_cost + = Costs2[j]
total_cost = dq[ 0 ] + (j - i + 1 ) * running_cost
if total_cost > budget:
running_cost - = Costs2[i]
if dq[ 0 ] = = Costs1[i]:
dq.popleft()
i + = 1
else :
ans = max (ans, j - i + 1 )
j + = 1
return ans
if __name__ = = '__main__' :
Costs1 = [ 3 , 6 , 1 , 3 , 4 ]
Costs2 = [ 2 , 1 , 3 , 4 , 5 ]
budget = 25
print (maximum_objects(Costs1, Costs2, budget))
|
C#
using System;
using System.Collections.Generic;
using System.Linq;
class Program {
static int MaximumObjects(List< int > Costs1,
List< int > Costs2, int budget)
{
int n = Costs1.Count;
int totalCost = 0, runningCost = 0;
int i = 0, j = 0, ans = 0;
Queue< int > dq = new Queue< int >();
while (j < n) {
while (dq.Any() && Costs1[j] >= dq.Last())
dq.Dequeue();
dq.Enqueue(Costs1[j]);
runningCost += Costs2[j];
totalCost
= dq.Peek() + (j - i + 1) * runningCost;
if (totalCost > budget) {
runningCost -= Costs2[i];
if (dq.Peek() == Costs1[i])
dq.Dequeue();
i++;
}
else
ans = Math.Max(ans, j - i + 1);
j++;
}
return ans;
}
static void Main( string [] args)
{
List< int > Costs1 = new List< int >{ 3, 6, 1, 3, 4 };
List< int > Costs2 = new List< int >{ 2, 1, 3, 4, 5 };
int budget = 25;
Console.WriteLine(
MaximumObjects(Costs1, Costs2, budget));
}
}
|
Javascript
function maximumObjects(Costs1, Costs2, budget) {
let n = Costs1.length;
let totalCost = 0, runningCost = 0;
let i = 0, j = 0, ans = 0;
let dq = [];
while (j < n) {
while (dq.length !== 0 && Costs1[j] >= dq[dq.length - 1])
dq.pop();
dq.push(Costs1[j]);
runningCost += Costs2[j];
totalCost = dq[0] + (j - i + 1) * runningCost;
if (totalCost > budget) {
runningCost -= Costs2[i];
if (dq[0] === Costs1[i])
dq.shift();
i++;
}
else
ans = Math.max(ans, j - i + 1);
j++;
}
return ans;
}
let Costs1 = [3, 6, 1, 3, 4];
let Costs2 = [2, 1, 3, 4, 5];
let budget = 25;
console.log(maximumObjects(Costs1, Costs2, budget));
|
Time Complexity: O(N*logN), Where N is the size of the array
Auxiliary Space: O(N)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...