# Generate a combination of minimum coins that sums to a given value

Given an array arr[] of size N representing the available denominations and an integer X. The task is to find any combination of the minimum number of coins of the available denominations such that the sum of the coins is X. If the given sum cannot be obtained by the available denominations, print -1.

Examples:

Input: X = 21, arr[] = {2, 3, 4, 5}
Output: 2 4 5 5 5
Explanation:
One possible solution is {2, 4, 5, 5, 5} where 2 + 4 + 5 + 5 + 5 = 21.
Another possible solution is {3, 3, 5, 5, 5}.

Input: X = 1, arr[] = {2, 4, 6, 9}
Output: -1
Explanation:
All coins are greater than 1. Hence, no solution exist.

Naive Approach: The simplest approach is to try all possible combinations of given denominations such that in each combination, the sum of coins is equal to X. From these combinations, choose the one having the minimum number of coins and print it. If the sum any combinations is not equal to X, print -1
Time Complexity: O(XN)
Auxiliary Space: O(N)

Efficient Approach: The above approach can be optimized using Dynamic Programming to find the minimum number of coins. While finding the minimum number of coins, backtracking can be used to track the coins needed to make their sum equals to X. Follow the below steps to solve the problem:

1. Initialize an auxiliary array dp[], where dp[i] will store the minimum number of coins needed to make sum equals to i.
2. Find the minimum number of coins needed to make their sum equals to X using the approach discussed in this article.
3. After finding the minimum number of coins use the Backtracking Technique to track down the coins used, to make the sum equals to X.
4. In backtracking, traverse the array and choose a coin which is smaller than the current sum such that dp[current_sum] equals to dp[current_sum – chosen_coin]+1. Store the chosen coin in an array.
5. After completing the above step, backtrack again by passing the current sum as (current sum – chosen coin value).
6. After finding the solution, print the array of chosen coins.

Below is the implementation of the above approach:

## C++

 `// C++ program for the above approach`   `#include ` `using` `namespace` `std;` `#define MAX 100000`   `// dp array to memoize the results` `int` `dp[MAX + 1];`   `// List to store the result` `list<``int``> denomination;`   `// Function to find the minimum number of` `// coins to make the sum equals to X` `int` `countMinCoins(``int` `n, ``int` `C[], ``int` `m)` `{` `    ``// Base case` `    ``if` `(n == 0) {` `        ``dp = 0;` `        ``return` `0;` `    ``}`   `    ``// If previously computed` `    ``// subproblem occurred` `    ``if` `(dp[n] != -1)` `        ``return` `dp[n];`   `    ``// Initialize result` `    ``int` `ret = INT_MAX;`   `    ``// Try every coin that has smaller` `    ``// value than n` `    ``for` `(``int` `i = 0; i < m; i++) {`   `        ``if` `(C[i] <= n) {`   `            ``int` `x` `                ``= countMinCoins(n - C[i],` `                                ``C, m);`   `            ``// Check for INT_MAX to avoid` `            ``// overflow and see if result` `            ``// can be minimized` `            ``if` `(x != INT_MAX)` `                ``ret = min(ret, 1 + x);` `        ``}` `    ``}`   `    ``// Memoizing value of current state` `    ``dp[n] = ret;` `    ``return` `ret;` `}`   `// Function to find the possible` `// combination of coins to make` `// the sum equal to X` `void` `findSolution(``int` `n, ``int` `C[], ``int` `m)` `{` `    ``// Base Case` `    ``if` `(n == 0) {`   `        ``// Print Solutions` `        ``for` `(``auto` `it : denomination) {` `            ``cout << it << ``' '``;` `        ``}`   `        ``return``;` `    ``}`   `    ``for` `(``int` `i = 0; i < m; i++) {`   `        ``// Try every coin that has` `        ``// value smaller than n` `        ``if` `(n - C[i] >= 0` `            ``and dp[n - C[i]] + 1` `                    ``== dp[n]) {`   `            ``// Add current denominations` `            ``denomination.push_back(C[i]);`   `            ``// Backtrack` `            ``findSolution(n - C[i], C, m);` `            ``break``;` `        ``}` `    ``}` `}`   `// Function to find the minimum` `// combinations of coins for value X` `void` `countMinCoinsUtil(``int` `X, ``int` `C[],` `                       ``int` `N)` `{`   `    ``// Initialize dp with -1` `    ``memset``(dp, -1, ``sizeof``(dp));`   `    ``// Min coins` `    ``int` `isPossible` `        ``= countMinCoins(X, C,` `                        ``N);`   `    ``// If no solution exists` `    ``if` `(isPossible == INT_MAX) {` `        ``cout << ``"-1"``;` `    ``}`   `    ``// Backtrack to find the solution` `    ``else` `{` `        ``findSolution(X, C, N);` `    ``}` `}`   `// Driver code` `int` `main()` `{` `    ``int` `X = 21;`   `    ``// Set of possible denominations` `    ``int` `arr[] = { 2, 3, 4, 5 };`   `    ``int` `N = ``sizeof``(arr) / ``sizeof``(arr);`   `    ``// Function Call` `    ``countMinCoinsUtil(X, arr, N);`   `    ``return` `0;` `}`

## Java

 `// Java program for ` `// the above approach` `import` `java.util.*;` `class` `GFG{` `  `  `static` `final` `int` `MAX = ``100000``;`   `// dp array to memoize the results` `static` `int` `[]dp = ``new` `int``[MAX + ``1``];`   `// List to store the result` `static` `List denomination = ` `            ``new` `LinkedList();`   `// Function to find the minimum ` `// number of coins to make the ` `// sum equals to X` `static` `int` `countMinCoins(``int` `n, ` `                         ``int` `C[], ``int` `m)` `{` `  ``// Base case` `  ``if` `(n == ``0``) ` `  ``{` `    ``dp[``0``] = ``0``;` `    ``return` `0``;` `  ``}`   `  ``// If previously computed` `  ``// subproblem occurred` `  ``if` `(dp[n] != -``1``)` `    ``return` `dp[n];`   `  ``// Initialize result` `  ``int` `ret = Integer.MAX_VALUE;`   `  ``// Try every coin that has smaller` `  ``// value than n` `  ``for` `(``int` `i = ``0``; i < m; i++) ` `  ``{` `    ``if` `(C[i] <= n) ` `    ``{` `      ``int` `x = countMinCoins(n - C[i],` `                            ``C, m);`   `      ``// Check for Integer.MAX_VALUE to avoid` `      ``// overflow and see if result` `      ``// can be minimized` `      ``if` `(x != Integer.MAX_VALUE)` `        ``ret = Math.min(ret, ``1` `+ x);` `    ``}` `  ``}`   `  ``// Memoizing value of current state` `  ``dp[n] = ret;` `  ``return` `ret;` `}`   `// Function to find the possible` `// combination of coins to make` `// the sum equal to X` `static` `void` `findSolution(``int` `n, ` `                         ``int` `C[], ``int` `m)` `{` `  ``// Base Case` `  ``if` `(n == ``0``) ` `  ``{` `    ``// Print Solutions` `    ``for` `(``int` `it : denomination) ` `    ``{` `      ``System.out.print(it + ``" "``);` `    ``}` `    ``return``;` `  ``}`   `  ``for` `(``int` `i = ``0``; i < m; i++) ` `  ``{` `    ``// Try every coin that has` `    ``// value smaller than n` `    ``if` `(n - C[i] >= ``0` `&& ` `        ``dp[n - C[i]] + ``1` `== ` `        ``dp[n]) ` `    ``{` `      ``// Add current denominations` `      ``denomination.add(C[i]);`   `      ``// Backtrack` `      ``findSolution(n - C[i], C, m);` `      ``break``;` `    ``}` `  ``}` `}`   `// Function to find the minimum` `// combinations of coins for value X` `static` `void` `countMinCoinsUtil(``int` `X, ` `                              ``int` `C[], ``int` `N)` `{` `  ``// Initialize dp with -1` `  ``for` `(``int` `i = ``0``; i < dp.length; i++)` `    ``dp[i] = -``1``;`   `  ``// Min coins` `  ``int` `isPossible = countMinCoins(X, C, N);`   `  ``// If no solution exists` `  ``if` `(isPossible == Integer.MAX_VALUE) ` `  ``{` `    ``System.out.print(``"-1"``);` `  ``}`   `  ``// Backtrack to find the solution` `  ``else` `  ``{` `    ``findSolution(X, C, N);` `  ``}` `}`   `// Driver code` `public` `static` `void` `main(String[] args)` `{` `  ``int` `X = ``21``;`   `  ``// Set of possible denominations` `  ``int` `arr[] = {``2``, ``3``, ``4``, ``5``};`   `  ``int` `N = arr.length;`   `  ``// Function Call` `  ``countMinCoinsUtil(X, arr, N);` `}` `}`   `// This code is contributed by Rajput-Ji`

## Python3

 `# Python3 program for the above approach` `import` `sys`   `MAX` `=` `100000`   `# dp array to memoize the results` `dp ``=` `[``-``1``] ``*` `(``MAX` `+` `1``)`   `# List to store the result` `denomination ``=` `[]`   `# Function to find the minimum number of` `# coins to make the sum equals to X` `def` `countMinCoins(n, C, m):` `    `  `    ``# Base case` `    ``if` `(n ``=``=` `0``):` `        ``dp[``0``] ``=` `0` `        ``return` `0`   `    ``# If previously computed` `    ``# subproblem occurred` `    ``if` `(dp[n] !``=` `-``1``):` `        ``return` `dp[n]`   `    ``# Initialize result` `    ``ret ``=` `sys.maxsize`   `    ``# Try every coin that has smaller` `    ``# value than n` `    ``for` `i ``in` `range``(m):` `        ``if` `(C[i] <``=` `n):` `            ``x ``=` `countMinCoins(n ``-` `C[i], C, m)`   `            ``# Check for INT_MAX to avoid` `            ``# overflow and see if result` `            ``#. an be minimized` `            ``if` `(x !``=` `sys.maxsize):` `                ``ret ``=` `min``(ret, ``1` `+` `x)`   `    ``# Memoizing value of current state` `    ``dp[n] ``=` `ret` `    ``return` `ret`   `# Function to find the possible` `# combination of coins to make` `# the sum equal to X` `def` `findSolution(n, C, m):` `    `  `    ``# Base Case` `    ``if` `(n ``=``=` `0``):`   `        ``# Print Solutions` `        ``for` `it ``in` `denomination:` `            ``print``(it, end ``=` `" "``)`   `        ``return`   `    ``for` `i ``in` `range``(m):`   `        ``# Try every coin that has` `        ``# value smaller than n` `        ``if` `(n ``-` `C[i] >``=` `0` `and` `         ``dp[n ``-` `C[i]] ``+` `1` `=``=` `dp[n]):`   `            ``# Add current denominations` `            ``denomination.append(C[i])`   `            ``# Backtrack` `            ``findSolution(n ``-` `C[i], C, m)` `            ``break`   `# Function to find the minimum` `# combinations of coins for value X` `def` `countMinCoinsUtil(X, C,N):`   `    ``# Initialize dp with -1` `    ``# memset(dp, -1, sizeof(dp))`   `    ``# Min coins` `    ``isPossible ``=` `countMinCoins(X, C,N)`   `    ``# If no solution exists` `    ``if` `(isPossible ``=``=` `sys.maxsize):` `        ``print``(``"-1"``)`   `    ``# Backtrack to find the solution` `    ``else``:` `        ``findSolution(X, C, N)`   `# Driver code` `if` `__name__ ``=``=` `'__main__'``:` `    `  `    ``X ``=` `21`   `    ``# Set of possible denominations` `    ``arr ``=` `[ ``2``, ``3``, ``4``, ``5` `]`   `    ``N ``=` `len``(arr)`   `    ``# Function call` `    ``countMinCoinsUtil(X, arr, N)`   `# This code is contributed by mohit kumar 29`

## C#

 `// C# program for ` `// the above approach` `using` `System;` `using` `System.Collections.Generic;` `class` `GFG{` `  `  `static` `readonly` `int` `MAX = 100000;`   `// dp array to memoize the results` `static` `int` `[]dp = ``new` `int``[MAX + 1];`   `// List to store the result` `static` `List<``int``> denomination = ` `            ``new` `List<``int``>();`   `// Function to find the minimum ` `// number of coins to make the ` `// sum equals to X` `static` `int` `countMinCoins(``int` `n, ` `                         ``int` `[]C, ` `                         ``int` `m)` `{` `  ``// Base case` `  ``if` `(n == 0) ` `  ``{` `    ``dp = 0;` `    ``return` `0;` `  ``}`   `  ``// If previously computed` `  ``// subproblem occurred` `  ``if` `(dp[n] != -1)` `    ``return` `dp[n];`   `  ``// Initialize result` `  ``int` `ret = ``int``.MaxValue;`   `  ``// Try every coin that has smaller` `  ``// value than n` `  ``for` `(``int` `i = 0; i < m; i++) ` `  ``{` `    ``if` `(C[i] <= n) ` `    ``{` `      ``int` `x = countMinCoins(n - C[i],` `                            ``C, m);`   `      ``// Check for int.MaxValue to avoid` `      ``// overflow and see if result` `      ``// can be minimized` `      ``if` `(x != ``int``.MaxValue)` `        ``ret = Math.Min(ret, 1 + x);` `    ``}` `  ``}`   `  ``// Memoizing value of current state` `  ``dp[n] = ret;` `  ``return` `ret;` `}`   `// Function to find the possible` `// combination of coins to make` `// the sum equal to X` `static` `void` `findSolution(``int` `n, ` `                         ``int` `[]C, ` `                         ``int` `m)` `{` `  ``// Base Case` `  ``if` `(n == 0) ` `  ``{` `    ``// Print Solutions` `    ``foreach` `(``int` `it ``in` `denomination) ` `    ``{` `      ``Console.Write(it + ``" "``);` `    ``}` `    ``return``;` `  ``}`   `  ``for` `(``int` `i = 0; i < m; i++) ` `  ``{` `    ``// Try every coin that has` `    ``// value smaller than n` `    ``if` `(n - C[i] >= 0 && ` `        ``dp[n - C[i]] + 1 == ` `        ``dp[n]) ` `    ``{` `      ``// Add current denominations` `      ``denomination.Add(C[i]);`   `      ``// Backtrack` `      ``findSolution(n - C[i], C, m);` `      ``break``;` `    ``}` `  ``}` `}`   `// Function to find the minimum` `// combinations of coins for value X` `static` `void` `countMinCoinsUtil(``int` `X, ` `                              ``int` `[]C, ` `                              ``int` `N)` `{` `  ``// Initialize dp with -1` `  ``for` `(``int` `i = 0; i < dp.Length; i++)` `    ``dp[i] = -1;`   `  ``// Min coins` `  ``int` `isPossible = countMinCoins(X, C, N);`   `  ``// If no solution exists` `  ``if` `(isPossible == ``int``.MaxValue) ` `  ``{` `    ``Console.Write(``"-1"``);` `  ``}`   `  ``// Backtrack to find the solution` `  ``else` `  ``{` `    ``findSolution(X, C, N);` `  ``}` `}`   `// Driver code` `public` `static` `void` `Main(String[] args)` `{` `  ``int` `X = 21;`   `  ``// Set of possible denominations` `  ``int` `[]arr = {2, 3, 4, 5};`   `  ``int` `N = arr.Length;`   `  ``// Function Call` `  ``countMinCoinsUtil(X, arr, N);` `}` `}`   `// This code is contributed by shikhasingrajput`

Output:

```2 4 5 5 5

```

Time Complexity: O(N*X), where N is the length of the given array and X is the given integer.
Auxiliary Space: O(N)

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.

My Personal Notes arrow_drop_up Check out this Author's contributed articles.

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.

Be the First to upvote.

Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.