📜  购买至少 X 块巧克力的最低成本

📅  最后修改于: 2021-09-17 16:00:55             🧑  作者: Mango

给定一个正整数X和一个由N对组成的数组arr[] ,其中每一对(A, B)代表一个盒子,其中A代表巧克力的数量, B代表当前盒子的成本。任务是找到购买至少X 块巧克力的最低成本。

例子:

朴素方法:最简单的方法是使用递归,考虑盒子的所有子集并计算所有子集的巧克力的成本和数量。从所有这些子集中,选择具有最低成本和至少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)