Open In App

Minimum cost to buy N kilograms of sweet for M persons

Improve
Improve
Like Article
Like
Save
Share
Report

Given an array of n sizes, it includes the cost of sweets in such a way 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][0][j] element with 0 and sweet[i][j][0] 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]

Implementation:

C++




// C++ program to minimum cost to buy
// N kilograms of sweet for M persons
#include <bits/stdc++.h>
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




<script>
// Javascript program to minimum cost to buy
// N kilograms of sweet for M persons
     
    // Function to find the minimum cost of sweets
    function find(m,n,adj)
    {
        // Defining the sweet array
        let sweet = new Array(n + 1) ;
         
        // DP array to store the values
        let dp = new Array(n + 1) ;
        for (let i = 0; i <n+1; ++i) {
            dp[i]=new Array(n+1);
            for (let j = 0; j <= n; ++j) {
                dp[i][j]=new Array(n+1);
                    for (let k = 0; k <= n; ++k) {
         
                        dp[i][j][k] = -1;
                      }
            }
        }
        sweet[0] = 0;
         
        // Since index starts from 1 we
        // reassign the array into sweet
        for (let i = 1; i <= m; ++i)
            sweet[i] = adj[i - 1];
         
        // Assigning base cases for dp array
        for (let i = 0; i <= m; ++i) {
            for (let k = 0; k <= n; ++k)
         
                // At 0 it is free
                dp[i][0][k] = 0;
         
            // Package not available for desirable amount of sweets
            for (let k = 1; k <= n; ++k)
                dp[i][k][0] = -1;
        }
         
        for (let i = 0; i <= m; ++i) {
             
            for (let j = 1; j <= n; ++j) {
                for (let 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
    let m = 3;
    let adj=[2, 1, 3, 0, 4, 10];
    let n = adj.length ;
    document.write( find(m, n, adj));
 
// This code is contributed by avanitrachhadiya2155
</script>


Output

2




Time complexity: O(m*n*n)
Auxiliary Space: O(n3)

Efficient approach : Space optimization

In previous approach the current value dp[i][j] is only depend upon the current and previous row values of DP. So to optimize the space complexity we use a single 1D array to store the computations.

Implementation steps:

  • Create a 2D vector dp of size (n+1) x (n+1).
  • Set a base case by initializing the values of DP .
  • Now iterate over subproblems by the help of nested loop and get the current value from previous computations.
  • At last return and print the final answer stored in dp[m][n].

Implementation: 

C++




#include <bits/stdc++.h>
using namespace std;
 
// Function to find the minimum cost of sweets
int find(int m, int n, int adj[])
{
    // Defining the sweet array
    vector<int> sweet(n + 1);
 
    // DP array to store the values
    vector<vector<int>> dp(n + 1, vector<int>(n + 1, -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) {
        // At 0 it is free
        dp[i][0] = 0;
 
        // Package not available for desirable amount of sweets
        dp[i][1] = (sweet[1] > 0) ? sweet[1] : -1;
    }
 
    for (int i = 0; i <= m; ++i) {
        for (int j = 1; j <= n; ++j) {
 
            // Buying the 'j' kg package and
            // assigning it to dp array
            if (i > 0 && sweet[j] > 0 && j <= n
                && dp[i - 1][j - 1] != -1)
                dp[i][j] = dp[i - 1][j - 1] + sweet[j];
 
            // If no solution, select from previous packages
            if (dp[i][j] == -1 || (j > 1 && dp[i][j - 1] != -1
                                        && dp[i][j] > dp[i][j - 1]))
                dp[i][j] = dp[i][j - 1];
        }
    }
 
    // If solution does not exist
    if (dp[m][n] == -1)
        return 0;
 
    // Print the solution
    else
        return dp[m][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




import java.util.*;
 
public class Main {
  public 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];
 
    for (int i = 0; i <= n; i++) {
      Arrays.fill(dp[i], -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++) {
      // At 0 it is free
      dp[i][0] = 0;
 
      // Package not available for desirable amount of sweets
      dp[i][1] = (sweet[1] > 0) ? sweet[1] : -1;
    }
 
    for (int i = 0; i <= m; i++) {
      for (int j = 1; j <= n; j++) {
        // Buying the 'j' kg package and
        // assigning it to dp array
        if (i > 0 && sweet[j] > 0 && j <= n && dp[i - 1][j - 1] != -1) {
          dp[i][j] = dp[i - 1][j - 1] + sweet[j];
        }
 
        // If no solution, select from previous packages
        if (dp[i][j] == -1 || (j > 1 && dp[i][j - 1] != -1 && dp[i][j] > dp[i][j - 1])) {
          dp[i][j] = dp[i][j - 1];
        }
      }
    }
 
    // If solution does not exist
    if (dp[m][n] == -1) {
      return 0;
    }
 
    // Print the solution
    else {
      return dp[m][n];
    }
  }
 
  // Driver Function
  public static void main(String[] args) {
    int m = 3;
    int[] adj = {2, 1, 3, 0, 4, 10};
    int n = adj.length;
 
    // Calling the desired function
    System.out.println(find(m, n, adj));
  }
}


Python3




# 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 = [[-1 for _ in range(n + 1)] for _ 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):
        # At 0, it is free
        dp[i][0] = 0
 
        # Package not available for the desirable amount of sweets
        dp[i][1] = sweet[1] if sweet[1] > 0 else -1
 
    for i in range(m + 1):
        for j in range(1, n + 1):
            # Buying the 'j' kg package and assigning it to dp array
            if i > 0 and sweet[j] > 0 and j <= n and dp[i - 1][j - 1] != -1:
                dp[i][j] = dp[i - 1][j - 1] + sweet[j]
 
            # If no solution, select from previous packages
            if dp[i][j] == -1 or (j > 1 and dp[i][j - 1] != -1 and dp[i][j] > dp[i][j - 1]):
                dp[i][j] = dp[i][j - 1]
 
    # If the solution does not exist
    if dp[m][n] == -1:
        return 0
 
    # Return the solution
    return dp[m][n]
 
# Driver Function
if __name__ == "__main__":
    m = 3
    adj = [2, 1, 3, 0, 4, 10]
    n = len(adj)
 
    # Calling the desired function
    result = find(m, n, adj)
    print(result)


C#




using System;
 
class Program
{
    // 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][];
        for (int i = 0; i <= n; i++)
        {
            dp[i] = new int[n + 1];
            for (int j = 0; j <= n; j++)
            {
                dp[i][j] = -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++)
        {
            // At 0 it is free
            dp[i][0] = 0;
 
            // Package not available for the desirable amount of sweets
            dp[i][1] = (sweet[1] > 0) ? sweet[1] : -1;
        }
 
        for (int i = 0; i <= m; i++)
        {
            for (int j = 1; j <= n; j++)
            {
                // Buying the 'j' kg package and assigning it to dp array
                if (i > 0 && sweet[j] > 0 && j <= n && dp[i - 1][j - 1] != -1)
                {
                    dp[i][j] = dp[i - 1][j - 1] + sweet[j];
                }
 
                // If no solution, select from previous packages
                if (dp[i][j] == -1 || (j > 1 && dp[i][j - 1] != -1 && dp[i][j] > dp[i][j - 1]))
                {
                    dp[i][j] = dp[i][j - 1];
                }
            }
        }
 
        // If a solution does not exist
        if (dp[m][n] == -1)
        {
            return 0;
        }
        // Return the solution
        else
        {
            return dp[m][n];
        }
    }
 
    // Driver Function
    static void Main()
    {
        int m = 3;
        int[] adj = { 2, 1, 3, 0, 4, 10 };
        int n = adj.Length;
 
        // Calling the desired function
        int result = Find(m, n, adj);
        Console.WriteLine(result);
    }
}


Javascript




function find(m, n, adj) {
    // Define the sweet array
    const sweet = new Array(n + 1);
 
    // DP array to store the values
    const dp = new Array(n + 1);
    for (let i = 0; i <= n; i++) {
        dp[i] = new Array(n + 1).fill(-1);
    }
 
    sweet[0] = 0;
 
    // Since index starts from 1, we reassign the array into sweet
    for (let i = 1; i <= m; i++) {
        sweet[i] = adj[i - 1];
    }
 
    // Assign base cases for dp array
    for (let i = 0; i <= m; i++) {
        // At 0, it is free
        dp[i][0] = 0;
 
        // Package not available for the desirable amount of sweets
        dp[i][1] = sweet[1] > 0 ? sweet[1] : -1;
    }
 
    for (let i = 0; i <= m; i++) {
        for (let j = 1; j <= n; j++) {
            // Buying the 'j' kg package and assigning it to dp array
            if (i > 0 && sweet[j] > 0 && j <= n && dp[i - 1][j - 1] !== -1) {
                dp[i][j] = dp[i - 1][j - 1] + sweet[j];
            }
 
            // If no solution, select from previous packages
            if (dp[i][j] === -1 || (j > 1 && dp[i][j - 1] !== -1 && dp[i][j] > dp[i][j - 1])) {
                dp[i][j] = dp[i][j - 1];
            }
        }
    }
 
    // If a solution does not exist
    if (dp[m][n] === -1) {
        return 0;
    } else {
        // Return the solution
        return dp[m][n];
    }
}
 
// Driver Function
function main() {
    const m = 3;
    const adj = [2, 1, 3, 0, 4, 10];
    const n = adj.length;
 
    // Calling the desired function
    const result = find(m, n, adj);
    console.log(result);
}
 
main();


Output

2

Time complexity: O(m*n)
Auxiliary Space: O(n^2)



Last Updated : 27 Nov, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads