📜  为M人购买N公斤甜食的最低成本

📅  最后修改于: 2021-04-30 02:30:35             🧑  作者: Mango

给定一个大小为n的数组包含糖果的成本,以使得sweet [i]是i糖果的成本。任务是找到为“ m”个人购买恰好“ n”公斤甜食的最低花费。

由于小包中有糖果,因此您必须为“ m”个亲戚购买最多“ m”个小包。您不能购买超过“ m”包的糖果。同样cost [i] = 0,表示具有数据包大小i的sweet不可用。同样,有无数个大小为i的小包。

例子

方法:

  1. 创建矩阵sweet [m + 1] [n + 1] [n + 1],其中m是亲戚数量,n是要购买的总甜品公斤和甜品包装数量。
  2. 用0初始化sweet [i] [0] [j]元素,并用-1初始化sweet [i] [j] [0]。
  3. 现在根据以下规则填充矩阵–
    • 购买“ k”软件包并将其分配给dp阵列。如果i> 0且j> =当前包装数且k个糖果的价格大于0。将dp定义为d p [i-1] [jk] [k] + sweet [k]
    • 如果dp未定义,请从以前的k-1个软件包中选择-> dp [i] [j] [k] = dp [i] [j] [k-1]
  4. 如果dp [m] [n] [n]为-1,则答案为0,否则打印dp [m] [n] [n]

下面是上述方法的实现:

C++
// C++ program to minimum cost to buy 
// N kilograms of sweet for M persons
#include 
using namespace std;
  
// Function to find the minimum cost of sweets
int find(int m, int n, int adj[])
{
    // Defining the sweet array
    int sweet[n + 1];
  
    // DP array to store the values
    int dp[n + 1][n + 1][n + 1];
  
    sweet[0] = 0;
  
    // Since index starts from 1 we
    // reassign the array into sweet
    for (int i = 1; i <= m; ++i)
        sweet[i] = adj[i - 1];
  
    // Assigning base cases for dp array
    for (int i = 0; i <= m; ++i) {
        for (int k = 0; k <= n; ++k)
  
            // At 0 it is free
            dp[i][0][k] = 0;
  
        // Package not available for desirable amount of sweets
        for (int k = 1; k <= n; ++k)
            dp[i][k][0] = -1;
    }
  
    for (int i = 0; i <= m; ++i) {
        for (int j = 1; j <= n; ++j) {
            for (int k = 1; k <= n; ++k) {
  
                dp[i][j][k] = -1;
  
                // Buying the 'k' kg package and
                // assigning it to dp array
                if (i > 0 && j >= k && sweet[k] > 0
                    && dp[i - 1][j - k][k] != -1)
  
                    dp[i][j][k] = dp[i - 1][j - k][k] + sweet[k];
  
                // If no solution, select from previous k-1 packages
                if (dp[i][j][k] == -1 || (dp[i][j][k - 1] != -1
                                          && dp[i][j][k] > dp[i][j][k - 1]))
  
                    dp[i][j][k] = dp[i][j][k - 1];
            }
        }
    }
  
    // If solution does not exist
    if (dp[m][n][n] == -1)
        return 0;
  
    // Print the solution
    else
        return dp[m][n][n];
}
  
// Driver Function
int main()
{
    int m = 3;
    int adj[] = { 2, 1, 3, 0, 4, 10 };
    int n = sizeof(adj) / sizeof(adj[0]);
  
    // Calling the desired function
    cout << find(m, n, adj);
    return 0;
}


Java
// Java program to minimum cost to buy 
// N kilograms of sweet for M persons
public class GFG {
      
    // Function to find the minimum cost of sweets 
    static int find(int m, int n, int adj[]) 
    { 
        // Defining the sweet array 
        int sweet[] = new int [n + 1] ;
        
        // DP array to store the values 
        int dp[][][] = new int [n + 1][n + 1][n + 1] ;
        
        sweet[0] = 0; 
        
        // Since index starts from 1 we 
        // reassign the array into sweet 
        for (int i = 1; i <= m; ++i) 
            sweet[i] = adj[i - 1]; 
        
        // Assigning base cases for dp array 
        for (int i = 0; i <= m; ++i) { 
            for (int k = 0; k <= n; ++k) 
        
                // At 0 it is free 
                dp[i][0][k] = 0; 
        
            // Package not available for desirable amount of sweets 
            for (int k = 1; k <= n; ++k) 
                dp[i][k][0] = -1; 
        } 
        
        for (int i = 0; i <= m; ++i) { 
            for (int j = 1; j <= n; ++j) { 
                for (int k = 1; k <= n; ++k) { 
        
                    dp[i][j][k] = -1; 
        
                    // Buying the 'k' kg package and 
                    // assigning it to dp array 
                    if (i > 0 && j >= k && sweet[k] > 0 
                        && dp[i - 1][j - k][k] != -1) 
        
                        dp[i][j][k] = dp[i - 1][j - k][k] + sweet[k]; 
        
                    // If no solution, select from previous k-1 packages 
                    if (dp[i][j][k] == -1 || (dp[i][j][k - 1] != -1 
                                              && dp[i][j][k] > dp[i][j][k - 1])) 
        
                        dp[i][j][k] = dp[i][j][k - 1]; 
                } 
            } 
        } 
        
        // If solution does not exist 
        if (dp[m][n][n] == -1) 
            return 0; 
        
        // Print the solution 
        else
            return dp[m][n][n]; 
    } 
  
    // Driver code
    public static void main(String args[])
    {
        int m = 3; 
        int adj[] = { 2, 1, 3, 0, 4, 10 }; 
        int n = adj.length ; 
        System.out.println( find(m, n, adj));
    }
    // This Code is contributed by ANKITRAI1
}


Python
# Python3 program to minimum cost to buy
# N kilograms of sweet for M persons
  
# Function to find the minimum cost of sweets
def find(m, n, adj):
      
    # Defining the sweet array
    sweet = [0] * (n + 1)
  
    # DP array to store the values
    dp = [[[ 0 for i in range(n + 1)] for i in range(n + 1)] for i in range(n + 1)]
  
    sweet[0] = 0
  
    # Since index starts from 1 we
    # reassign the array into sweet
    for i in range(1, m + 1):
        sweet[i] = adj[i - 1]
  
    # Assigning base cases for dp array
    for i in range(m + 1):
        for k in range(n + 1):
  
            # At 0 it is free
            dp[i][0][k] = 0
  
        # Package not available for desirable amount of sweets
        for k in range(1, n + 1):
            dp[i][k][0] = -1
  
  
    for i in range(m + 1):
        for j in range(1, n + 1):
            for k in range(1, n + 1):
  
                dp[i][j][k] = -1
  
                # Buying the 'k' kg package and
                # assigning it to dp array
                if (i > 0 and j >= k and sweet[k] > 0 and dp[i - 1][j - k][k] != -1):
  
                    dp[i][j][k] = dp[i - 1][j - k][k] + sweet[k]
  
                # If no solution, select from previous k-1 packages
                if (dp[i][j][k] == -1 or (dp[i][j][k - 1] != -1 and dp[i][j][k] > dp[i][j][k - 1])):
  
                    dp[i][j][k] = dp[i][j][k - 1]
  
    # If solution does not exist
    if (dp[m][n][n] == -1):
        return 0
  
    # Print the solution
    else:
        return dp[m][n][n]
  
# Driver Function
  
m = 3
adj = [2, 1, 3, 0, 4, 10]
n = len(adj)
  
# Calling the desired function
print(find(m, n, adj))
  
# This code is contributed by mohit kumar 29


C#
// C# program to minimum cost to buy 
// N kilograms of sweet for M persons
using System;
  
class GFG 
{
  
// Function to find the minimum 
// cost of sweets 
static int find(int m, int n, 
                int[] adj) 
{ 
    // Defining the sweet array 
    int[] sweet = new int [n + 1] ;
      
    // DP array to store the values 
    int[,,] dp = new int [n + 1, n + 1, 
                                 n + 1];
      
    sweet[0] = 0; 
      
    // Since index starts from 1 we 
    // reassign the array into sweet 
    for (int i = 1; i <= m; ++i) 
        sweet[i] = adj[i - 1]; 
      
    // Assigning base cases 
    // for dp array 
    for (int i = 0; i <= m; ++i)
    { 
        for (int k = 0; k <= n; ++k) 
      
            // At 0 it is free 
            dp[i, 0, k] = 0; 
      
        // Package not available for 
        // desirable amount of sweets 
        for (int k = 1; k <= n; ++k) 
            dp[i, k, 0] = -1; 
    } 
      
    for (int i = 0; i <= m; ++i) 
    { 
        for (int j = 1; j <= n; ++j) 
        { 
            for (int k = 1; k <= n; ++k) 
            { 
      
                dp[i, j, k] = -1; 
      
                // Buying the 'k' kg package and 
                // assigning it to dp array 
                if (i > 0 && j >= k && sweet[k] > 0 && 
                    dp[i - 1, j - k, k] != -1) 
      
                    dp[i, j, k] = dp[i - 1, j - k, k] + 
                                             sweet[k]; 
      
                // If no solution, select from
                // previous k-1 packages 
                if (dp[i, j, k] == -1 || 
                   (dp[i, j, k - 1] != -1 &&
                    dp[i, j, k] > dp[i, j, k - 1])) 
      
                    dp[i, j, k] = dp[i, j, k - 1]; 
            } 
        } 
    } 
      
    // If solution does not exist 
    if (dp[m, n, n] == -1) 
        return 0; 
      
    // Print the solution 
    else
        return dp[m, n, n]; 
} 
  
// Driver code
public static void Main()
{
    int m = 3; 
    int[] adj = { 2, 1, 3, 0, 4, 10 }; 
    int n = adj.Length ; 
    Console.Write(find(m, n, adj));
}
}
  
// This code is contributed
// by ChitraNayal
// C# program to minimum cost to buy 
// N kilograms of sweet for M persons
using System;
  
class GFG 
{
  
// Function to find the minimum 
// cost of sweets 
static int find(int m, int n, 
                int[] adj) 
{ 
    // Defining the sweet array 
    int[] sweet = new int [n + 1] ;
      
    // DP array to store the values 
    int[,,] dp = new int [n + 1, n + 1, 
                                 n + 1];
      
    sweet[0] = 0; 
      
    // Since index starts from 1 we 
    // reassign the array into sweet 
    for (int i = 1; i <= m; ++i) 
        sweet[i] = adj[i - 1]; 
      
    // Assigning base cases 
    // for dp array 
    for (int i = 0; i <= m; ++i)
    { 
        for (int k = 0; k <= n; ++k) 
      
            // At 0 it is free 
            dp[i, 0, k] = 0; 
      
        // Package not available for 
        // desirable amount of sweets 
        for (int k = 1; k <= n; ++k) 
            dp[i, k, 0] = -1; 
    } 
      
    for (int i = 0; i <= m; ++i) 
    { 
        for (int j = 1; j <= n; ++j) 
        { 
            for (int k = 1; k <= n; ++k) 
            { 
      
                dp[i, j, k] = -1; 
      
                // Buying the 'k' kg package and 
                // assigning it to dp array 
                if (i > 0 && j >= k && sweet[k] > 0 && 
                    dp[i - 1, j - k, k] != -1) 
      
                    dp[i, j, k] = dp[i - 1, j - k, k] + 
                                             sweet[k]; 
      
                // If no solution, select from
                // previous k-1 packages 
                if (dp[i, j, k] == -1 || 
                   (dp[i, j, k - 1] != -1 &&
                    dp[i, j, k] > dp[i, j, k - 1])) 
      
                    dp[i, j, k] = dp[i, j, k - 1]; 
            } 
        } 
    } 
      
    // If solution does not exist 
    if (dp[m, n, n] == -1) 
        return 0; 
      
    // Print the solution 
    else
        return dp[m, n, n]; 
} 
  
// Driver code
public static void Main()
{
    int m = 3; 
    int[] adj = { 2, 1, 3, 0, 4, 10 }; 
    int n = adj.Length ; 
    Console.Write(find(m, n, adj));
}
}
  
// This code is contributed
// by ChitraNayal


输出:
3

上述算法的时间复杂度为O(m * n * n)。