Given the areas of Small, Medium, and Large pizzas as s, m, and l units, and their respective costs as cs, cm, and cl, find the minimum cost required to buy pizzas whose total area is at least x.
Any number of pizzas of each type can be purchased.
Examples:
Input: x = 16, s = 3, m = 6, l = 9, cs = 50, cm = 150, cl = 300
Output: 300
Explanation: Six Small pizzas give a total area of 6 Ã 3 = 18 at a cost of 6 Ã 50 = 300. Other combinations such as one Small, one Medium and one Large give an area of 18 at a cost of 500, while two Large pizzas cost 600. Hence, the minimum cost is 300.Input: x = 10, s = 1, m = 3, l = 10, cs = 10, cm = 20, cl = 50
Output: 50
Explanation: One Large pizza provides exactly 10 square units of area at a cost of 50. Hence, the minimum cost is 50.
Table of Content
[Naive Approach] Recursion - Exponential Time and O(x) Auxiliary Space
The idea is to recursively try all possible combinations of Small, Medium, and Large pizzas and return the minimum cost among them.
- Start with area = 0.
- If area >= x, the required area is reached, so return 0.
Otherwise, buy one pizza of each type recursively and take the minimum cost.
- small = cs + minCost(..., area + s)
- medium = cm + minCost(..., area + m)
- large = cl + minCost(..., area + l)
- answer = min(small, medium, large)
#include <bits/stdc++.h>
using namespace std;
int minCost(int x, int s, int m, int l,
int cs, int cm, int cl, int area) {
// If required area is reached, return the current cost
if (area >= x)
return 0;
// Buy one Small pizza
int small = cs + minCost(x, s, m, l, cs, cm, cl, area + s);
// Buy one Medium pizza
int medium = cm + minCost(x, s, m, l, cs, cm, cl, area + m);
// Buy one Large pizza
int large = cl + minCost(x, s, m, l, cs, cm, cl, area + l);
// Return the minimum cost
return min(small, min(medium, large));
}
int minimumCost(int x, int s, int m, int l,
int cs, int cm, int cl) {
return minCost(x, s, m, l, cs, cm, cl, 0);
}
int main() {
int x = 16;
int s = 3, m = 6, l = 9;
int cs = 50, cm = 150, cl = 300;
cout << minimumCost(x, s, m, l, cs, cm, cl) << endl;
return 0;
}
class GFG {
static int minCost(int x, int s, int m, int l,
int cs, int cm, int cl, int area) {
// If required area is reached, return the current cost
if (area >= x)
return 0;
// Buy one Small pizza
int small = cs + minCost(x, s, m, l, cs, cm, cl, area + s);
// Buy one Medium pizza
int medium = cm + minCost(x, s, m, l, cs, cm, cl, area + m);
// Buy one Large pizza
int large = cl + minCost(x, s, m, l, cs, cm, cl, area + l);
// Return the minimum cost
return Math.min(small, Math.min(medium, large));
}
static int minimumCost(int x, int s, int m, int l,
int cs, int cm, int cl) {
return minCost(x, s, m, l, cs, cm, cl, 0);
}
public static void main(String[] args) {
int x = 16;
int s = 3, m = 6, l = 9;
int cs = 50, cm = 150, cl = 300;
System.out.println(minimumCost(x, s, m, l, cs, cm, cl));
}
}
def minCost(x, s, m, l, cs, cm, cl, area):
# If required area is reached, return the current cost
if area >= x:
return 0
# Buy one Small pizza
small = cs + minCost(x, s, m, l, cs, cm, cl, area + s)
# Buy one Medium pizza
medium = cm + minCost(x, s, m, l, cs, cm, cl, area + m)
# Buy one Large pizza
large = cl + minCost(x, s, m, l, cs, cm, cl, area + l)
# Return the minimum cost
return min(small, min(medium, large))
def minimumCost(x, s, m, l, cs, cm, cl):
return minCost(x, s, m, l, cs, cm, cl, 0)
if __name__ == "__main__":
x = 16
s = 3
m = 6
l = 9
cs = 50
cm = 150
cl = 300
print(minimumCost(x, s, m, l, cs, cm, cl))
using System;
class GFG {
public static int minCost(int x, int s, int m, int l,
int cs, int cm, int cl, int area) {
// If required area is reached, return the current cost
if (area >= x)
return 0;
// Buy one Small pizza
int small = cs + minCost(x, s, m, l, cs, cm, cl, area + s);
// Buy one Medium pizza
int medium = cm + minCost(x, s, m, l, cs, cm, cl, area + m);
// Buy one Large pizza
int large = cl + minCost(x, s, m, l, cs, cm, cl, area + l);
// Return the minimum cost
return Math.Min(small, Math.Min(medium, large));
}
public static int minimumCost(int x, int s, int m, int l,
int cs, int cm, int cl) {
return minCost(x, s, m, l, cs, cm, cl, 0);
}
public static void Main() {
int x = 16;
int s = 3, m = 6, l = 9;
int cs = 50, cm = 150, cl = 300;
Console.WriteLine(minimumCost(x, s, m, l, cs, cm, cl));
}
}
function minCost(x, s, m, l, cs, cm, cl, area)
{
// If required area is reached, return the current cost
if (area >= x)
return 0;
// Buy one Small pizza
let small
= cs + minCost(x, s, m, l, cs, cm, cl, area + s);
// Buy one Medium pizza
let medium
= cm + minCost(x, s, m, l, cs, cm, cl, area + m);
// Buy one Large pizza
let large
= cl + minCost(x, s, m, l, cs, cm, cl, area + l);
// Return the minimum cost
return Math.min(small, Math.min(medium, large));
}
function minimumCost(x, s, m, l, cs, cm, cl)
{
return minCost(x, s, m, l, cs, cm, cl, 0);
}
// Driver code
let x = 16;
let s = 3, m = 6, l = 9;
let cs = 50, cm = 150, cl = 300;
console.log(minimumCost(x, s, m, l, cs, cm, cl));
Output
300
[Expected Approach] Dynamic Programming - O(x) Time and O(x) Auxiliary Space
The idea is to use Dynamic Programming to store the minimum cost required to obtain each possible pizza area.
Let dp[i] represent the minimum cost required to obtain exactly i units of pizza area.
Since the required area is at least x, the final area can be greater than x. Before buying the last pizza, the total area is less than x. Since the largest pizza adds at most l units, the first area that reaches or exceeds x can be at most x + l.
Hence, set: limit = x + l
Initialize dp[0] = 0 and all other values to INT_MAX.
For every reachable area i, try adding one Small, Medium, or Large pizza and update the minimum cost for the resulting area:
- dp[i + s] = min(dp[i + s], dp[i] + cs)
- dp[i + m] = min(dp[i + m], dp[i] + cm)
- dp[i + l] = min(dp[i + l], dp[i] + cl)
Since the required area is at least x, check all areas from x to x + l and return the minimum cost.
#include <bits/stdc++.h>
using namespace std;
int minimumCost(int x, int s, int m, int l,
int cs, int cm, int cl) {
// Compute DP up to the maximum useful area.
int limit = x + l;
vector<int> dp(limit + 1, INT_MAX);
dp[0] = 0;
// Build minimum cost for every achievable area.
for (int i = 0; i <= limit; i++) {
if (dp[i] == INT_MAX)
continue;
if (i + s <= limit)
dp[i + s] = min(dp[i + s], dp[i] + cs);
if (i + m <= limit)
dp[i + m] = min(dp[i + m], dp[i] + cm);
if (i + l <= limit)
dp[i + l] = min(dp[i + l], dp[i] + cl);
}
// Find the minimum cost for an area of at least x.
int res = INT_MAX;
for (int i = x; i <= limit; i++)
res = min(res, dp[i]);
return res;
}
int main() {
int x = 16;
int s = 3, m = 6, l = 9;
int cs = 50, cm = 150, cl = 300;
cout << minimumCost(x, s, m, l, cs, cm, cl) << endl;
return 0;
}
import java.util.Arrays;
class GFG {
static int minimumCost(int x, int s, int m, int l,
int cs, int cm, int cl) {
// Compute DP up to the maximum useful area.
int limit = x + l;
int[] dp = new int[limit + 1];
Arrays.fill(dp, Integer.MAX_VALUE);
dp[0] = 0;
// Build minimum cost for every achievable area.
for (int i = 0; i <= limit; i++) {
if (dp[i] == Integer.MAX_VALUE)
continue;
if (i + s <= limit)
dp[i + s] = Math.min(dp[i + s], dp[i] + cs);
if (i + m <= limit)
dp[i + m] = Math.min(dp[i + m], dp[i] + cm);
if (i + l <= limit)
dp[i + l] = Math.min(dp[i + l], dp[i] + cl);
}
// Find the minimum cost for an area of at least x.
int res = Integer.MAX_VALUE;
for (int i = x; i <= limit; i++)
res = Math.min(res, dp[i]);
return res;
}
public static void main(String[] args) {
int x = 16;
int s = 3, m = 6, l = 9;
int cs = 50, cm = 150, cl = 300;
System.out.println(minimumCost(x, s, m, l, cs, cm, cl));
}
}
def minimumCost(x, s, m, l, cs, cm, cl):
# Compute DP up to the maximum useful area.
limit = x + l
dp = [float('inf')] * (limit + 1)
dp[0] = 0
# Build minimum cost for every achievable area.
for i in range(limit + 1):
if dp[i] == float('inf'):
continue
if i + s <= limit:
dp[i + s] = min(dp[i + s], dp[i] + cs)
if i + m <= limit:
dp[i + m] = min(dp[i + m], dp[i] + cm)
if i + l <= limit:
dp[i + l] = min(dp[i + l], dp[i] + cl)
# Find the minimum cost for an area of at least x.
res = float('inf')
for i in range(x, limit + 1):
res = min(res, dp[i])
return res
if __name__ == "__main__":
x = 16
s = 3
m = 6
l = 9
cs = 50
cm = 150
cl = 300
print(minimumCost(x, s, m, l, cs, cm, cl))
using System;
class GFG {
public static int minimumCost(int x, int s, int m, int l,
int cs, int cm, int cl) {
// Compute DP up to the maximum useful area.
int limit = x + l;
int[] dp = new int[limit + 1];
Array.Fill(dp, int.MaxValue);
dp[0] = 0;
// Build minimum cost for every achievable area.
for (int i = 0; i <= limit; i++) {
if (dp[i] == int.MaxValue)
continue;
if (i + s <= limit)
dp[i + s] = Math.Min(dp[i + s], dp[i] + cs);
if (i + m <= limit)
dp[i + m] = Math.Min(dp[i + m], dp[i] + cm);
if (i + l <= limit)
dp[i + l] = Math.Min(dp[i + l], dp[i] + cl);
}
// Find the minimum cost for an area of at least x.
int res = int.MaxValue;
for (int i = x; i <= limit; i++)
res = Math.Min(res, dp[i]);
return res;
}
public static void Main() {
int x = 16;
int s = 3, m = 6, l = 9;
int cs = 50, cm = 150, cl = 300;
Console.WriteLine(minimumCost(x, s, m, l, cs, cm, cl));
}
}
function minimumCost(x, s, m, l, cs, cm, cl)
{
// Compute DP up to the maximum useful area.
let limit = x + l;
let dp = new Array(limit + 1).fill(Infinity);
dp[0] = 0;
// Build minimum cost for every achievable area.
for (let i = 0; i <= limit; i++) {
if (dp[i] === Infinity)
continue;
if (i + s <= limit)
dp[i + s] = Math.min(dp[i + s], dp[i] + cs);
if (i + m <= limit)
dp[i + m] = Math.min(dp[i + m], dp[i] + cm);
if (i + l <= limit)
dp[i + l] = Math.min(dp[i + l], dp[i] + cl);
}
// Find the minimum cost for an area of at least x.
let res = Infinity;
for (let i = x; i <= limit; i++)
res = Math.min(res, dp[i]);
return res;
}
// Driver code
let x = 16;
let s = 3, m = 6, l = 9;
let cs = 50, cm = 150, cl = 300;
console.log(minimumCost(x, s, m, l, cs, cm, cl));
Output
300