Given an array price[], where price[i] represents the price of a stock on the (i + 1)th day, and an integer k representing the amount of money available. On the (i + 1)th day, a customer can buy at most (i + 1) stocks.
Find the maximum number of stocks that can be purchased without exceeding the available amount.
Examples:
Input: price[] = [10,7,19], k = 45
Output: 4
Explanation: Buy 1 stock on day 1 for 10, 2 stocks on day 2 for 7 each, and 1 stock on day 3 for 19. The total amount spent is 10 + (2 × 7) + 19 = 43, so the maximum number of stocks purchased is 4.Input: price[] = [7,10, 4], k = 100
Output: 6
Explanation: Buy 3 stocks on day 3 for 4 each, 1 stock on day 1 for 7, and 2 stocks on day 2 for 10 each. Hence, the maximum number of stocks purchased is 6.
Table of Content
[Naive Approach] Try All Possible Purchases (Recursion) - Exponential Time and O(n) Space
The idea is to process the days one by one and recursively try buying every possible number of stocks on each day. On the (i + 1)th day, we can buy from 0 to (i + 1) stocks, as long as the total cost does not exceed the remaining amount.
For each valid choice, recursively solve the remaining days with the updated budget and return the maximum number of stocks that can be purchased. Since the same states are recomputed multiple times, this approach is inefficient for large inputs.
#include <bits/stdc++.h>
using namespace std;
int solve(int day, int money, vector<int> &price) {
// All days processed
if (day == price.size())
return 0;
int ans = 0;
// Try buying 0 to (day + 1) stocks
for (int buy = 0; buy <= day + 1; buy++) {
int cost = buy * price[day];
if (cost <= money) {
ans = max(ans, buy +
solve(day + 1, money - cost, price));
}
}
return ans;
}
int buyMaximumProducts(int k, vector<int> &price) {
return solve(0, k, price);
}
int main() {
vector<int> price = {10, 7, 19};
int k = 45;
cout << buyMaximumProducts(k, price);
return 0;
}
class GFG {
public static int solve(int day, int money, int[] price) {
// All days processed
if (day == price.length)
return 0;
int ans = 0;
// Try buying 0 to (day + 1) stocks
for (int buy = 0; buy <= day + 1; buy++) {
int cost = buy * price[day];
if (cost <= money) {
ans = Math.max(ans, buy +
solve(day + 1, money - cost, price));
}
}
return ans;
}
public static int buyMaximumProducts(int k, int[] price) {
return solve(0, k, price);
}
public static void main(String[] args) {
int[] price = {10, 7, 19};
int k = 45;
System.out.println(buyMaximumProducts(k, price));
}
}
def solve(day, money, price):
# All days processed
if day == len(price):
return 0
ans = 0
# Try buying 0 to (day + 1) stocks
for buy in range(day + 2):
cost = buy * price[day]
if cost <= money:
ans = max(ans,
buy + solve(day + 1,
money - cost,
price))
return ans
def buyMaximumProducts(k, price):
return solve(0, k, price)
if __name__ == "__main__":
price = [10, 7, 19]
k = 45
print(buyMaximumProducts(k, price))
using System;
using System.Collections.Generic;
class GFG {
static int solve(int day, int money, int[] price) {
// All days processed
if (day == price.Length)
return 0;
int ans = 0;
// Try buying 0 to (day + 1) stocks
for (int buy = 0; buy <= day + 1; buy++) {
int cost = buy * price[day];
if (cost <= money) {
ans = Math.Max(ans, buy +
solve(day + 1, money - cost, price));
}
}
return ans;
}
static int buyMaximumProducts(int[] price, int k) {
return solve(0, k, price);
}
static void Main() {
int[] price = {10, 7, 19};
int k = 45;
Console.WriteLine(buyMaximumProducts(price, k));
}
}
function solve(day, money, price) {
// All days processed
if (day === price.length)
return 0;
let ans = 0;
// Try buying 0 to (day + 1) stocks
for (let buy = 0; buy <= day + 1; buy++) {
let cost = buy * price[day];
if (cost <= money) {
ans = Math.max(ans,
buy + solve(day + 1,
money - cost,
price));
}
}
return ans;
}
function buyMaximumProducts(k, price) {
return solve(0, k, price);
}
// Driver code
let price = [10, 7, 19];
let k = 45;
console.log(buyMaximumProducts(k, price));
Output
4
[Expected Approach] Using Greedy with Sorting - O(n log n) Time and O(n) Space
The idea is to always buy the cheapest stocks first. Since every purchased stock contributes equally to the answer, spending the available budget on lower-priced stocks maximizes the total number of stocks that can be bought.
Create a list of pairs (price, day), where day denotes the maximum number of stocks that can be purchased on that day. Sort these pairs in ascending order of stock price.
Traverse the sorted list and, for each pair, buy as many stocks as possible without exceeding either the day's purchase limit or the remaining budget. Update the answer and reduce the remaining amount accordingly.
Consider: price[] = [10, 7, 19], k = 45
Create the (price, day) pairs: (10, 1), (7, 2), (19, 3)
After sorting by price: (7, 2), (10, 1), (19, 3)
Initially, k = 45 and ans = 0.
- For (7, 2), buy min(2, 45 / 7) = 2 stocks. Update k = 31 and ans = 2.
- For (10, 1), buy min(1, 31 / 10) = 1 stock. Update k = 21 and ans = 3.
- For (19, 3), buy min(3, 21 / 19) = 1 stock. Update k = 2 and ans = 4.
After processing all the pairs, the maximum number of stocks that can be purchased is 4.
#include <iostream>
#include <vector>
#include <algorithm>
#include <utility>
using namespace std;
// Return the maximum stocks
int buyMaximumProducts(int k, vector<int> price) {
int n = price.size() ;
vector<pair<int, int> > v;
// Making pair of product cost and number
for (int i = 0; i < n; ++i)
v.push_back(make_pair(price[i], i + 1));
// Sorting the vector pair.
sort(v.begin(), v.end());
// Calculating the maximum number of stock
int ans = 0;
for (int i = 0; i < n; i++) {
ans += min(v[i].second, k / v[i].first);
k -= v[i].first * min(v[i].second,
(k / v[i].first));
}
return ans;
}
int main() {
vector<int> price = { 10, 7, 19 };
int k = 45;
cout << buyMaximumProducts(k, price) << endl;
return 0;
}
import java.util.Arrays;
public class GFG {
// Return the maximum stocks
static int buyMaximumProducts(int k, int[] price) {
int n = price.length;
// 2D array where each row is {price, max_quantity_allowed}
int[][] arr = new int[n][2];
for (int i = 0; i < n; i++) {
// Store price
arr[i][0] = price[i];
// Store day (which is the max quantity)
arr[i][1] = i + 1;
}
// Sort the 2D array based on the price (column 0) in ascending order
Arrays.sort(arr, (a, b) -> Integer.compare(a[0], b[0]));
int ans = 0;
for (int i = 0; i < n; i++) {
int currentPrice = arr[i][0];
int maxQuantity = arr[i][1];
// Calculate how many stocks we can actually buy
int count = Math.min(maxQuantity, k / currentPrice);
ans += count;
// Deduct the spent money from k
k -= currentPrice * count;
}
return ans;
}
public static void main(String[] args) {
int[] price = { 10, 7, 19 };
int k = 45;
System.out.println(buyMaximumProducts(k, price));
}
}
# Returns the maximum stocks
def buyMaximumProducts(k, price):
n = len(price) # Calculating n inside the function
# Making pair of stock cost and day number
arr = []
for i in range(n):
arr.append([i + 1, price[i]])
# Sort based on the price of stock
arr.sort(key = lambda x: x[1])
# Calculating the max stocks purchased
total_purchase = 0
for i in range(n):
P = min(arr[i][0], k // arr[i][1])
total_purchase += P
k -= (P * arr[i][1])
return total_purchase
if __name__ == "__main__":
price = [ 10, 7, 19 ]
k = 45
print(buyMaximumProducts(k, price))
using System;
using System.Collections.Generic;
class GFG {
// Return the maximum stocks
static int buyMaximumProducts(int[] price, int k) {
int n = price.Length;
List<(int, int)> v = new List<(int, int)>();
// Making pair of product cost and number
for (int i = 0; i < n; ++i)
v.Add((price[i], i + 1));
// Sorting the vector pair.
v.Sort((a, b) => a.Item1.CompareTo(b.Item1));
// Calculating the maximum number of stock
int ans = 0;
for (int i = 0; i < n; i++) {
ans += Math.Min(v[i].Item2, k / v[i].Item1);
k -= v[i].Item1 * Math.Min(v[i].Item2,
k / v[i].Item1);
}
return ans;
}
static void Main() {
int[] price = {10, 7, 19};
int k = 45;
Console.WriteLine(buyMaximumProducts(price, k));
}
}
// Return the maximum stocks
function buyMaximumProducts(k, price) {
let n = price.length;
// 2D array where each row is [price, max_quantity_allowed]
let arr = [];
for (let i = 0; i < n; i++) {
// Store price and day (which is the max quantity)
arr.push([price[i], i + 1]);
}
// Sort the 2D array based on the price in ascending order
arr.sort((a, b) => a[0] - b[0]);
let ans = 0;
for (let i = 0; i < n; i++) {
let currentPrice = arr[i][0];
let maxQuantity = arr[i][1];
// Calculate how many stocks we can actually buy
let count = Math.min(maxQuantity,
Math.floor(k / currentPrice));
ans += count;
// Deduct the spent money from k
k -= currentPrice * count;
}
return ans;
}
// Driver code
let price = [10, 7, 19];
let k = 45;
console.log(buyMaximumProducts(k, price));
Output
4