Minimum cost to buy N kilograms of sweet for M persons

Given an array of n size contains 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 sweet for the ‘m’ persons.

Since sweets are available in the packets, you have to buy at most ‘m’ packet of sweets for your ‘m’ relatives. You cannot buy more than ‘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 index but since you require at most 2 packets to obtain the 7 sweets packets answer which is not possible. Hence the answer is 0 as it is formed by 3 packets, not 2.

Approach:

  1. Create matrix sweet[m+1][n+1][n+1], where m is number of relatives and n is the total kg of sweets to be bought and number of packages of sweet.
  2. Initialize sweet[i][0][j] element with 0 and sweet[i][j][0] with -1.
  3. Now fill the matrix according to following rules –
    • Buy the ‘k’ package and assigning it to dp array. If i>0 and j>=Number of current packages and 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, answer is 0 otherwise print dp[m][n][n]

Below is the implementation of above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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
}
   

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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

chevron_right


Output:

3

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



My Personal Notes arrow_drop_up

Coder only XD Do send reference if contacting me

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.



Improved By : AnkitRai01, chitranayal