给定一个正整数X和一个由N对组成的数组arr[] ,其中每一对(A, B)代表一个盒子,其中A代表巧克力的数量, B代表当前盒子的成本。任务是找到购买至少X 块巧克力的最低成本。
例子:
Input: arr[] = {{4, 3}, {3, 2}, {2, 4}, {1, 3}, {4, 2}}, X = 7
Output: 4
Examples: Select the 2nd and the 5th box. Number of chocolates = 3 + 4 = 7.
Total cost = 2 + 2 = 4, which is the minimum cost to buy at least 7 chocolates.
Input: arr[] = {{10, 2}, {5, 3}}, X = 20
Output: -1
Examples: There exists no set of boxes which satisfies the given condition.
朴素方法:最简单的方法是使用递归,考虑盒子的所有子集并计算所有子集的巧克力的成本和数量。从所有这些子集中,选择具有最低成本和至少X 块巧克力的子集。
最优子结构:要考虑项目的所有子集,每个框可以有两种情况。
- 情况 1:该项目包含在最优子集中。如果包含当前盒子,则加上这个盒子的成本,并根据当前盒子中的巧克力数量减少X。并且对移动到下一个索引的剩余X巧克力重复。
- 情况 2:该项目未包含在最优集合中。如果当前的盒子不包括在内,那么只对剩余的X巧克力重复移动到下一个索引。
因此,可以得到的最小成本是上述两种情况中的最小值。如果X ≤ 0处理基本情况,则返回0 。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to calculate minimum cost
// of buying least X chocolates
int findMinCost(pair arr[],
int X, int n, int i = 0)
{
// Base Case
if (X <= 0)
return 0;
if (i >= n)
return INT_MAX;
// Include the i-th box
int inc = findMinCost(arr,
X - arr[i].first,
n, i + 1);
if (inc != INT_MAX)
inc += arr[i].second;
// Exclude the i-th box
int exc = findMinCost(arr, X, n, i + 1);
// Return the minimum of
// the above two cases
return min(inc, exc);
}
// Driver Code
int main()
{
// Given array and value of X
pair arr[] = {
{ 4, 3 }, { 3, 2 },
{ 2, 4 }, { 1, 3 }, { 4, 2 }
};
int X = 7;
// Store the size of the array
int n = sizeof(arr) / sizeof(arr[0]);
int ans = findMinCost(arr, X, n);
// Print the answer
if (ans != INT_MAX)
cout << ans;
else
cout << -1;
return 0;
}
Java
// Java program for above approach
class GFG{
// Function to calculate minimum cost
// of buying least X chocolates
static int findMinCost(int[][] arr, int X,
int n, int i)
{
// Base Case
if (X <= 0)
return 0;
if (i >= n)
return Integer.MAX_VALUE;
// Include the i-th box
int inc = findMinCost(arr, X - arr[i][0],
n, i + 1);
if (inc != Integer.MAX_VALUE)
inc += arr[i][1];
// Exclude the i-th box
int exc = findMinCost(arr, X, n, i + 1);
// Return the minimum of
// the above two cases
return Math.min(inc, exc);
}
// Driver Code
public static void main(String[] args)
{
// Given array and value of X
int[][] arr = { { 4, 3 }, { 3, 2 },
{ 2, 4 }, { 1, 3 },
{ 4, 2 } };
int X = 7;
// Store the size of the array
int n = arr.length;
int ans = findMinCost(arr, X, n, 0);
// Print the answer
if (ans != Integer.MAX_VALUE)
System.out.println(ans);
else
System.out.println(-1);
}
}
// This code is contributed by Hritik
Python3
# Python3 program for the above approach
# Function to calculate minimum cost
# of buying least X chocolates
def findMinCost(arr,X, n, i = 0):
# Base Case
if (X <= 0):
return 0
if (i >= n):
return 10**8
# Include the i-th box
inc = findMinCost(arr,X - arr[i][0], n, i + 1)
if (inc != 10**8):
inc += arr[i][1]
# Exclude the i-th box
exc = findMinCost(arr, X, n, i + 1)
# Return the minimum of
# the above two cases
return min(inc, exc)
# Driver Code
if __name__ == '__main__':
# Given array and value of X
arr = [[ 4, 3 ], [ 3, 2 ],[ 2, 4 ], [ 1, 3 ], [ 4, 2 ]]
X = 7
# Store the size of the array
n = len(arr)
ans = findMinCost(arr, X, n)
# Prthe answer
if (ans != 10**8):
print(ans)
else:
print(-1)
# This code is contributed by mohit kumar 29.
C#
// C# program for the above approach
using System;
class GFG
{
// Function to calculate minimum cost
// of buying least X chocolates
static int findMinCost(int[, ] arr, int X, int n,
int i = 0)
{
// Base Case
if (X <= 0)
return 0;
if (i >= n)
return Int32.MaxValue;
// Include the i-th box
int inc = findMinCost(arr, X - arr[i, 0], n, i + 1);
if (inc != Int32.MaxValue)
inc += arr[i, 1];
// Exclude the i-th box
int exc = findMinCost(arr, X, n, i + 1);
// Return the minimum of
// the above two cases
return Math.Min(inc, exc);
}
// Driver Code
public static void Main()
{
// Given array and value of X
int[, ] arr = {
{ 4, 3 }, { 3, 2 }, { 2, 4 }, { 1, 3 }, { 4, 2 }
};
int X = 7;
// Store the size of the array
int n = arr.GetLength(0);
int ans = findMinCost(arr, X, n);
// Print the answer
if (ans != Int32.MaxValue)
Console.Write(ans);
else
Console.Write(-1);
}
}
// This code is contributed by ukasp.
Javascript
C++
// C++ program for the above approach
#include
using namespace std;
// Recursive function to calculate minimum
// cost of buying at least X chocolates
int findMinCostUtil(pair arr[],
int X, int n,
int** dp, int i = 0)
{
// Base cases
if (X <= 0)
return 0;
if (i >= n)
return INT_MAX;
// If the state is already computed,
// return its result from the 2D array
if (dp[i][X] != INT_MAX)
return dp[i][X];
// Include the i-th box
int inc = findMinCostUtil(arr,
X - arr[i].first,
n, dp,
i + 1);
if (inc != INT_MAX)
inc += arr[i].second;
// Exclude the i-th box
int exc = findMinCostUtil(arr, X, n,
dp, i + 1);
// Update the result of
// the state in 2D array
dp[i][X] = min(inc, exc);
// Return the result
return dp[i][X];
}
// Function to find the minimum
// cost to buy at least X chocolates
void findMinCost(pair arr[], int X, int n)
{
// Create a 2D array, dp[][]
int** dp = new int*[n + 1];
// Initialize entries with INT_MAX
for (int i = 0; i <= n; i++) {
dp[i] = new int[X + 1];
for (int j = 0; j <= X; j++)
// Update dp[i][j]
dp[i][j] = INT_MAX;
}
// Stores the minimum cost required
int ans = findMinCostUtil(arr, X, n, dp);
// Print the answer
if (ans != INT_MAX)
cout << ans;
else
cout << -1;
}
// Driver Code
int main()
{
// Given array and value of X
pair arr[] = {
{ 4, 3 }, { 3, 2 },
{ 2, 4 }, { 1, 3 }, { 4, 2 }
};
int X = 7;
// Store the size of the array
int n = sizeof(arr) / sizeof(arr[0]);
findMinCost(arr, X, n);
return 0;
}
Java
// Java program for the above approach
class GFG{
// Recursive function to calculate minimum
// cost of buying at least X chocolates
static int findMinCostUtil(int[][] arr, int X, int n,
int[][] dp, int i)
{
// Base cases
if (X <= 0)
return 0;
if (i >= n)
return Integer.MAX_VALUE;
// If the state is already computed,
// return its result from the 2D array
if (dp[i][X] != Integer.MAX_VALUE)
return dp[i][X];
// Include the i-th box
int inc = findMinCostUtil(arr, X - arr[i][0],
n, dp, i + 1);
if (inc != Integer.MAX_VALUE)
inc += arr[i][1];
// Exclude the i-th box
int exc = findMinCostUtil(arr, X, n,
dp, i + 1);
// Update the result of
// the state in 2D array
dp[i][X] = Math.min(inc, exc);
// Return the result
return dp[i][X];
}
// Function to find the minimum
// cost to buy at least X chocolates
static void findMinCost(int[][] arr, int X, int n)
{
// Create a 2D array, dp[][]
int[][] dp = new int[n + 1][X + 1];
// Initialize entries with INT_MAX
for(int i = 0; i <= n; i++)
{
for(int j = 0; j <= X; j++)
// Update dp[i][j]
dp[i][j] = Integer.MAX_VALUE;
}
// Stores the minimum cost required
int ans = findMinCostUtil(arr, X, n, dp, 0);
// Print the answer
if (ans != Integer.MAX_VALUE)
System.out.println(ans);
else
System.out.println(-1);
}
// Driver code
public static void main(String[] args)
{
// Given array and value of X
int[][] arr = { { 4, 3 }, { 3, 2 },
{ 2, 4 }, { 1, 3 },
{ 4, 2 } };
int X = 7;
// Store the size of the array
int n = 5;
findMinCost(arr, X, n);
}
}
// This code is contributed by rameshtravel07
C#
// C# program for the above approach
using System;
class GFG
{
// Recursive function to calculate minimum
// cost of buying at least X chocolates
static int findMinCostUtil(int[,] arr, int X, int n, int[,] dp, int i)
{
// Base cases
if (X <= 0)
return 0;
if (i >= n)
return Int32.MaxValue;
// If the state is already computed,
// return its result from the 2D array
if (dp[i,X] != Int32.MaxValue)
return dp[i,X];
// Include the i-th box
int inc = findMinCostUtil(arr, X - arr[i,0], n, dp, i + 1);
if (inc != Int32.MaxValue)
inc += arr[i,1];
// Exclude the i-th box
int exc = findMinCostUtil(arr, X, n, dp, i + 1);
// Update the result of
// the state in 2D array
dp[i,X] = Math.Min(inc, exc);
// Return the result
return dp[i,X];
}
// Function to find the minimum
// cost to buy at least X chocolates
static void findMinCost(int[,] arr, int X, int n)
{
// Create a 2D array, dp[][]
int[,] dp = new int[n + 1, X + 1];
// Initialize entries with INT_MAX
for (int i = 0; i <= n; i++) {
for (int j = 0; j <= X; j++)
// Update dp[i][j]
dp[i,j] = Int32.MaxValue;
}
// Stores the minimum cost required
int ans = findMinCostUtil(arr, X, n, dp, 0);
// Print the answer
if (ans != Int32.MaxValue)
Console.WriteLine(ans);
else
Console.WriteLine(-1);
}
static void Main ()
{
// Given array and value of X
int[,] arr = {
{ 4, 3 }, { 3, 2 },
{ 2, 4 }, { 1, 3 }, { 4, 2 }
};
int X = 7;
// Store the size of the array
int n = 5;
findMinCost(arr, X, n);
}
}
// This code is contributed by suresh07.
Javascript
4
时间复杂度: O(2 N )
辅助空间: O(1)
高效方法:为了优化上述方法,思想是使用动态规划,因为问题包含重叠子问题和最优子结构属性。这个想法是使用记忆来解决问题。创建一个二维数组dp[N][X]以将结果存储在递归调用中。如果已经计算了特定状态,则在恒定时间内返回其存储在表中的结果。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Recursive function to calculate minimum
// cost of buying at least X chocolates
int findMinCostUtil(pair arr[],
int X, int n,
int** dp, int i = 0)
{
// Base cases
if (X <= 0)
return 0;
if (i >= n)
return INT_MAX;
// If the state is already computed,
// return its result from the 2D array
if (dp[i][X] != INT_MAX)
return dp[i][X];
// Include the i-th box
int inc = findMinCostUtil(arr,
X - arr[i].first,
n, dp,
i + 1);
if (inc != INT_MAX)
inc += arr[i].second;
// Exclude the i-th box
int exc = findMinCostUtil(arr, X, n,
dp, i + 1);
// Update the result of
// the state in 2D array
dp[i][X] = min(inc, exc);
// Return the result
return dp[i][X];
}
// Function to find the minimum
// cost to buy at least X chocolates
void findMinCost(pair arr[], int X, int n)
{
// Create a 2D array, dp[][]
int** dp = new int*[n + 1];
// Initialize entries with INT_MAX
for (int i = 0; i <= n; i++) {
dp[i] = new int[X + 1];
for (int j = 0; j <= X; j++)
// Update dp[i][j]
dp[i][j] = INT_MAX;
}
// Stores the minimum cost required
int ans = findMinCostUtil(arr, X, n, dp);
// Print the answer
if (ans != INT_MAX)
cout << ans;
else
cout << -1;
}
// Driver Code
int main()
{
// Given array and value of X
pair arr[] = {
{ 4, 3 }, { 3, 2 },
{ 2, 4 }, { 1, 3 }, { 4, 2 }
};
int X = 7;
// Store the size of the array
int n = sizeof(arr) / sizeof(arr[0]);
findMinCost(arr, X, n);
return 0;
}
Java
// Java program for the above approach
class GFG{
// Recursive function to calculate minimum
// cost of buying at least X chocolates
static int findMinCostUtil(int[][] arr, int X, int n,
int[][] dp, int i)
{
// Base cases
if (X <= 0)
return 0;
if (i >= n)
return Integer.MAX_VALUE;
// If the state is already computed,
// return its result from the 2D array
if (dp[i][X] != Integer.MAX_VALUE)
return dp[i][X];
// Include the i-th box
int inc = findMinCostUtil(arr, X - arr[i][0],
n, dp, i + 1);
if (inc != Integer.MAX_VALUE)
inc += arr[i][1];
// Exclude the i-th box
int exc = findMinCostUtil(arr, X, n,
dp, i + 1);
// Update the result of
// the state in 2D array
dp[i][X] = Math.min(inc, exc);
// Return the result
return dp[i][X];
}
// Function to find the minimum
// cost to buy at least X chocolates
static void findMinCost(int[][] arr, int X, int n)
{
// Create a 2D array, dp[][]
int[][] dp = new int[n + 1][X + 1];
// Initialize entries with INT_MAX
for(int i = 0; i <= n; i++)
{
for(int j = 0; j <= X; j++)
// Update dp[i][j]
dp[i][j] = Integer.MAX_VALUE;
}
// Stores the minimum cost required
int ans = findMinCostUtil(arr, X, n, dp, 0);
// Print the answer
if (ans != Integer.MAX_VALUE)
System.out.println(ans);
else
System.out.println(-1);
}
// Driver code
public static void main(String[] args)
{
// Given array and value of X
int[][] arr = { { 4, 3 }, { 3, 2 },
{ 2, 4 }, { 1, 3 },
{ 4, 2 } };
int X = 7;
// Store the size of the array
int n = 5;
findMinCost(arr, X, n);
}
}
// This code is contributed by rameshtravel07
C#
// C# program for the above approach
using System;
class GFG
{
// Recursive function to calculate minimum
// cost of buying at least X chocolates
static int findMinCostUtil(int[,] arr, int X, int n, int[,] dp, int i)
{
// Base cases
if (X <= 0)
return 0;
if (i >= n)
return Int32.MaxValue;
// If the state is already computed,
// return its result from the 2D array
if (dp[i,X] != Int32.MaxValue)
return dp[i,X];
// Include the i-th box
int inc = findMinCostUtil(arr, X - arr[i,0], n, dp, i + 1);
if (inc != Int32.MaxValue)
inc += arr[i,1];
// Exclude the i-th box
int exc = findMinCostUtil(arr, X, n, dp, i + 1);
// Update the result of
// the state in 2D array
dp[i,X] = Math.Min(inc, exc);
// Return the result
return dp[i,X];
}
// Function to find the minimum
// cost to buy at least X chocolates
static void findMinCost(int[,] arr, int X, int n)
{
// Create a 2D array, dp[][]
int[,] dp = new int[n + 1, X + 1];
// Initialize entries with INT_MAX
for (int i = 0; i <= n; i++) {
for (int j = 0; j <= X; j++)
// Update dp[i][j]
dp[i,j] = Int32.MaxValue;
}
// Stores the minimum cost required
int ans = findMinCostUtil(arr, X, n, dp, 0);
// Print the answer
if (ans != Int32.MaxValue)
Console.WriteLine(ans);
else
Console.WriteLine(-1);
}
static void Main ()
{
// Given array and value of X
int[,] arr = {
{ 4, 3 }, { 3, 2 },
{ 2, 4 }, { 1, 3 }, { 4, 2 }
};
int X = 7;
// Store the size of the array
int n = 5;
findMinCost(arr, X, n);
}
}
// This code is contributed by suresh07.
Javascript
4
时间复杂度: O(N * X)
辅助空间: O(N * X)