📜  为M人购买N公斤糖果的最低成本

📅  最后修改于: 2021-09-22 10:06:57             🧑  作者: 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 为 dp [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


Javascript


输出:
3

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