Minimum cost to buy N kilograms of sweet for M persons

• Difficulty Level : Expert
• Last Updated : 21 May, 2021

Given an array of n sizes, it includes the cost of sweets in such a way that that sweet[i] is the cost of i sweets. The task is to find the minimum cost to spend to buy exactly ‘n’ kilograms of sweets for the ‘m’ people.
Since sweets are available in packets, you have to buy at most a ‘m’ packet of sweets for your ‘m’ relatives. You cannot buy more than a ‘m’ packet of sweets. Also, cost[i] = 0, represents that the sweet with packet size i is unavailable. Also, there is an infinite number of packets with i size of sweets.

Examples:

Input: m = 3, n = 6, arr[] = {2, 1, 3, 0, 4, 10}
Output: 3
We can choose at most 3 packets. We choose 3 packets of size 2, having cost 1 each.Thus, output is 3.

Input: m = 2, n = 7, arr[] = {1, 3, 0, 5, 0, 0, 0}
Output : 0
We can choose at most 2 packets. 7 can be formed by 1 2 and 4 indexes, but since you require at most 2 packets to obtain the 7 sweets packets sweet answer, which is not possible. Hence, the answer is 0 as it is formed by 3 packets, not 2.

Approach:

1. Create a matrix sweet[m+1][n+1][n+1], where m is the number of relatives and n is the total kg of sweets to be bought, and the number of packages of sweets.
2. Initialize sweet[i][j] element with 0 and sweet[i][j] with -1.
3. Now fill the matrix according to the following rules –
• Buy the ‘k’ package and assign it to dp array. If i>0 and j>=Number of current packages and the price of k sweets is greater than 0. Define dp as dp [i-1][j-k][k] + sweet[k]
• If dp is undefined, select from previous k-1 packages -> dp[i][j][k]=dp[i][j][k-1]
4. If dp[m][n][n] is -1, the answer is 0. Otherwise, print dp[m][n][n]

Below is the implementation of the above approach:

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 sweetsint 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;     // 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][k] = 0;         // Package not available for desirable amount of sweets        for (int k = 1; k <= n; ++k)            dp[i][k] = -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 Functionint main(){    int m = 3;    int adj[] = { 2, 1, 3, 0, 4, 10 };    int n = sizeof(adj) / sizeof(adj);     // 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 personspublic 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;               // 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][k] = 0;                   // Package not available for desirable amount of sweets            for (int k = 1; k <= n; ++k)                dp[i][k] = -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 sweetsdef find(m, n, adj):         # Defining the sweet array    sweet =  * (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     # 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][k] = 0         # Package not available for desirable amount of sweets        for k in range(1, n + 1):            dp[i][k] = -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 = 3adj = [2, 1, 3, 0, 4, 10]n = len(adj) # Calling the desired functionprint(find(m, n, adj)) # This code is contributed by mohit kumar 29

Javascript


Output:
3

The time complexity of the above algorithm is O(m*n*n).

My Personal Notes arrow_drop_up