Given an array coins[] of size N and a target value V, where coins[i] represents the coins of different denominations. You have an infinite supply of each of coins. The task is to find minimum number of coins required to make the given value V. If it’s not possible to make a change, print -1.
Examples:
Input: coins[] = {25, 10, 5}, V = 30
Output: Minimum 2 coins required We can use one coin of 25 cents and one of 5 cents
Input: coins[] = {9, 6, 5, 1}, V = 11
Output: Minimum 2 coins required We can use one coin of 6 cents and 1 coin of 5 cents
Find minimum number of coins to make a given value using Recursion
This problem is a variation of the problem discussed Coin Change Problem. Here instead of finding the total number of possible solutions, we need to find the solution with the minimum number of coins.
The minimum number of coins for a value V can be computed using the below recursive formula.
- If V == 0:
- If V > 0:
- minCoins(coins[0..m-1], V ) = min { 1 + minCoins(V-coin[i])} where, 0 <=i <= m-1 and coins[i] <= V.
Below is a implementation of the above approach:
C++
#include<bits/stdc++.h>
using namespace std;
int minCoins( int coins[], int m, int V)
{
if (V == 0) return 0;
int res = INT_MAX;
for ( int i=0; i<m; i++)
{
if (coins[i] <= V)
{
int sub_res = minCoins(coins, m, V-coins[i]);
if (sub_res != INT_MAX && sub_res + 1 < res)
res = sub_res + 1;
}
}
return res;
}
int main()
{
int coins[] = {9, 6, 5, 1};
int m = sizeof (coins)/ sizeof (coins[0]);
int V = 11;
cout << "Minimum coins required is "
<< minCoins(coins, m, V);
return 0;
}
|
Java
import java.io.*;
public class coin
{
static int minCoins( int coins[], int m, int V)
{
if (V == 0 ) return 0 ;
int res = Integer.MAX_VALUE;
for ( int i= 0 ; i<m; i++)
{
if (coins[i] <= V)
{
int sub_res = minCoins(coins, m, V-coins[i]);
if (sub_res != Integer.MAX_VALUE && sub_res + 1 < res)
res = sub_res + 1 ;
}
}
return res;
}
public static void main(String args[])
{
int coins[] = { 9 , 6 , 5 , 1 };
int m = coins.length;
int V = 11 ;
System.out.println( "Minimum coins required is " + minCoins(coins, m, V) );
}
}
|
Python3
import sys
def minCoins(coins, m, V):
if (V = = 0 ):
return 0
res = sys.maxsize
for i in range ( 0 , m):
if (coins[i] < = V):
sub_res = minCoins(coins, m, V - coins[i])
if (sub_res ! = sys.maxsize and sub_res + 1 < res):
res = sub_res + 1
return res
coins = [ 9 , 6 , 5 , 1 ]
m = len (coins)
V = 11
print ( "Minimum coins required is" ,minCoins(coins, m, V))
|
C#
using System;
class coin
{
static int minCoins( int []coins, int m, int V)
{
if (V == 0) return 0;
int res = int .MaxValue;
for ( int i = 0; i < m; i++)
{
if (coins[i] <= V)
{
int sub_res = minCoins(coins, m,
V - coins[i]);
if (sub_res != int .MaxValue &&
sub_res + 1 < res)
res = sub_res + 1;
}
}
return res;
}
public static void Main()
{
int []coins = {9, 6, 5, 1};
int m = coins.Length;
int V = 11;
Console.Write( "Minimum coins required is " +
minCoins(coins, m, V));
}
}
|
Javascript
<script>
function minCoins(coins, m, V)
{
if (V == 0)
return 0;
let res = Number.MAX_VALUE;
for (let i = 0; i < m; i++)
{
if (coins[i] <= V)
{
let sub_res = minCoins(coins, m,
V - coins[i]);
if (sub_res != Number.MAX_VALUE &&
sub_res + 1 < res)
res = sub_res + 1;
}
}
return res;
}
let coins = [ 9, 6, 5, 1 ];
let m = coins.length;
let V = 11;
document.write( "Minimum coins required is " +
minCoins(coins, m, V) );
</script>
|
PHP
<?php
function minCoins( $coins ,
$m , $V )
{
if ( $V == 0) return 0;
$res = PHP_INT_MAX;
for ( $i = 0; $i < $m ; $i ++)
{
if ( $coins [ $i ] <= $V )
{
$sub_res = minCoins( $coins , $m ,
$V - $coins [ $i ]);
if ( $sub_res != PHP_INT_MAX &&
$sub_res + 1 < $res )
$res = $sub_res + 1;
}
}
return $res ;
}
$coins = array (9, 6, 5, 1);
$m = sizeof( $coins );
$V = 11;
echo "Minimum coins required is " ,
minCoins( $coins , $m , $V );
?>
|
Output
Minimum coins required is 2
Time Complexity: O(m^V)
Auxiliary Space: O(V)
The idea is to find the Number of ways of Denominations By using the Top Down (Memoization).
Algorithm:
- Creating a 2-D vector to store the Overlapping Solutions
- Keep Track of the overlapping subproblems while Traversing the array coins[]
- Recall them whenever needed.
Below is the implementation using the Top Down Memoized Approach
C++
#include <bits/stdc++.h>
using namespace std;
int minCoinsUtil( int coins[], int m, int V, int * dp)
{
if (V == 0)
return 0;
if (dp[V] != -1)
return dp[V];
int res = INT_MAX;
for ( int i = 0; i < m; i++) {
if (coins[i] <= V) {
int sub_res
= minCoinsUtil(coins, m, V - coins[i], dp);
if (sub_res != INT_MAX && sub_res + 1 < res)
res = sub_res + 1;
}
}
dp[V] = res;
return res;
}
int minCoins( int coins[], int m, int V)
{
int * dp = new int [V + 1];
memset (dp, -1,
sizeof ( int )
* (V + 1));
return minCoinsUtil(coins, m, V, dp);
}
int main()
{
int coins[] = { 9, 6, 5, 1 };
int m = sizeof (coins) / sizeof (coins[0]);
int V = 11;
int res = minCoins(coins, m, V);
if (res == INT_MAX)
res = -1;
cout << "Minimum coins required is " << res;
return 0;
}
|
Java
import java.util.Arrays;
public class MinimumCoins {
public static int minCoinsUtil( int [] coins, int m,
int V, int [] dp)
{
if (V == 0 )
return 0 ;
if (dp[V] != - 1 )
return dp[V];
int res = Integer.MAX_VALUE;
for ( int i = 0 ; i < m; i++) {
if (coins[i] <= V) {
int sub_res = minCoinsUtil(
coins, m, V - coins[i], dp);
if (sub_res != Integer.MAX_VALUE
&& sub_res + 1 < res)
res = sub_res + 1 ;
}
}
dp[V] = res;
return res;
}
public static int minCoins( int [] coins, int m, int V)
{
int [] dp = new int [V + 1 ];
Arrays.fill(dp, - 1 );
return minCoinsUtil(coins, m, V, dp);
}
public static void main(String[] args)
{
int [] coins = { 9 , 6 , 5 , 1 };
int m = coins.length;
int V = 11 ;
int res = minCoins(coins, m, V);
if (res == Integer.MAX_VALUE)
res = - 1 ;
System.out.println( "Minimum coins required is "
+ res);
}
}
|
Python3
import sys
def minCoinsUtil(coins, m, V, dp):
if V = = 0 :
return 0
if dp[V] ! = - 1 :
return dp[V]
res = sys.maxsize
for i in range (m):
if coins[i] < = V:
sub_res = minCoinsUtil(coins, m, V - coins[i], dp)
if sub_res ! = sys.maxsize and sub_res + 1 < res:
res = sub_res + 1
dp[V] = res
return res
def minCoins(coins, m, V):
dp = [ - 1 ] * (V + 1 )
return minCoinsUtil(coins, m, V, dp)
if __name__ = = "__main__" :
coins = [ 9 , 6 , 5 , 1 ]
m = len (coins)
V = 11
res = minCoins(coins, m, V)
if res = = sys.maxsize:
res = - 1
print ( "Minimum coins required is" , res)
|
C#
using System;
class MinimumCoinChange
{
static int minCoinsUtil( int [] coins, int m, int V, int [] dp)
{
if (V == 0)
return 0;
if (dp[V] != -1)
return dp[V];
int res = int .MaxValue;
for ( int i = 0; i < m; i++)
{
if (coins[i] <= V)
{
int sub_res = minCoinsUtil(coins, m, V - coins[i], dp);
if (sub_res != int .MaxValue && sub_res + 1 < res)
res = sub_res + 1;
}
}
dp[V] = res;
return res;
}
static int minCoins( int [] coins, int m, int V)
{
int [] dp = new int [V + 1];
Array.Fill(dp, -1);
return minCoinsUtil(coins, m, V, dp);
}
static void Main( string [] args)
{
int [] coins = { 9, 6, 5, 1 };
int m = coins.Length;
int V = 11;
int res = minCoins(coins, m, V);
if (res == int .MaxValue)
res = -1;
Console.WriteLine( "Minimum coins required is " + res);
Console.ReadLine();
}
}
|
Javascript
function minCoinsUtil(coins, m, V, dp) {
if (V === 0) {
return 0;
}
if (dp[V] !== -1) {
return dp[V];
}
let res = Infinity;
for (let i = 0; i < m; i++) {
if (coins[i] <= V) {
let sub_res = minCoinsUtil(coins, m, V - coins[i], dp);
if (sub_res !== Infinity && sub_res + 1 < res) {
res = sub_res + 1;
}
}
}
dp[V] = res;
return res;
}
function minCoins(coins, m, V) {
const dp = new Array(V + 1).fill(-1);
return minCoinsUtil(coins, m, V, dp);
}
const coins = [9, 6, 5, 1];
const m = coins.length;
const V = 11;
const res = minCoins(coins, m,V);
if (res == Infinity) res = -1;
console.log( "Minimum coins required is" , res);
|
Output
Minimum coins required is 2
Time Complexity: O(m * V)
Auxiliary Space: (V)
Find minimum number of coins that make a given value using Dynamic Programming (Tabulation/ Bottom Up):
Since the same subproblems are called again, this problem has both properties Overlapping Subproblems and Optimal Substructure. Like other typical Dynamic Programming(DP) problems, recomputations of the same subproblems can be avoided by constructing a temporary array table[][] in a bottom-up manner.
Below is a implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int minCoins( int coins[], int m, int V)
{
int table[V + 1];
table[0] = 0;
for ( int i = 1; i <= V; i++)
table[i] = INT_MAX;
for ( int i = 1; i <= V; i++) {
for ( int j = 0; j < m; j++)
if (coins[j] <= i) {
int sub_res = table[i - coins[j]];
if (sub_res != INT_MAX
&& sub_res + 1 < table[i])
table[i] = sub_res + 1;
}
}
if (table[V] == INT_MAX)
return -1;
return table[V];
}
int main()
{
int coins[] = { 9, 6, 5, 1 };
int m = sizeof (coins) / sizeof (coins[0]);
int V = 11;
cout << "Minimum coins required is "
<< minCoins(coins, m, V);
return 0;
}
|
Java
import java.io.*;
class GFG
{
static int minCoins( int coins[], int m, int V)
{
int table[] = new int [V + 1 ];
table[ 0 ] = 0 ;
for ( int i = 1 ; i <= V; i++)
table[i] = Integer.MAX_VALUE;
for ( int i = 1 ; i <= V; i++)
{
for ( int j = 0 ; j < m; j++)
if (coins[j] <= i)
{
int sub_res = table[i - coins[j]];
if (sub_res != Integer.MAX_VALUE
&& sub_res + 1 < table[i])
table[i] = sub_res + 1 ;
}
}
if (table[V]==Integer.MAX_VALUE)
return - 1 ;
return table[V];
}
public static void main (String[] args)
{
int coins[] = { 9 , 6 , 5 , 1 };
int m = coins.length;
int V = 11 ;
System.out.println ( "Minimum coins required is "
+ minCoins(coins, m, V));
}
}
|
Python3
import sys
def minCoins(coins, m, V):
table = [ 0 for i in range (V + 1 )]
table[ 0 ] = 0
for i in range ( 1 , V + 1 ):
table[i] = sys.maxsize
for i in range ( 1 , V + 1 ):
for j in range (m):
if (coins[j] < = i):
sub_res = table[i - coins[j]]
if (sub_res ! = sys.maxsize and
sub_res + 1 < table[i]):
table[i] = sub_res + 1
if table[V] = = sys.maxsize:
return - 1
return table[V]
if __name__ = = "__main__" :
coins = [ 9 , 6 , 5 , 1 ]
m = len (coins)
V = 11
print ( "Minimum coins required is " ,
minCoins(coins, m, V))
|
C#
using System;
class GFG
{
static int minCoins( int []coins,
int m, int V)
{
int []table = new int [V + 1];
table[0] = 0;
for ( int i = 1; i <= V; i++)
table[i] = int .MaxValue;
for ( int i = 1; i <= V; i++)
{
for ( int j = 0; j < m; j++)
if (coins[j] <= i)
{
int sub_res = table[i - coins[j]];
if (sub_res != int .MaxValue &&
sub_res + 1 < table[i])
table[i] = sub_res + 1;
}
}
return table[V];
}
static public void Main ()
{
int []coins = {9, 6, 5, 1};
int m = coins.Length;
int V = 11;
Console.WriteLine( "Minimum coins required is " +
minCoins(coins, m, V));
}
}
|
Javascript
<script>
function minCoins(coins,m,v)
{
let table = new Array(V+1);
table[0] = 0;
for (let i = 1; i <= V; i++)
{
table[i] = Number.MAX_VALUE;
}
for (let i = 1; i <= V; i++)
{
for (let j = 0; j < m; j++)
if (coins[j] <= i)
{
let sub_res = table[i - coins[j]];
if (sub_res != Number.MAX_VALUE
&& sub_res + 1 < table[i])
table[i] = sub_res + 1;
}
}
if (table[V] == Number.MAX_VALUE)
return -1;
return table[V];
}
let coins = [9, 6, 5, 1];
let m = coins.length;
let V = 11;
document.write( "Minimum coins required is " + minCoins(coins, m, V))
</script>
|
PHP
<?php
function minCoins( $coins , $m , $V )
{
$table [ $V + 1] = array ();
$table [0] = 0;
for ( $i = 1; $i <= $V ; $i ++)
$table [ $i ] = PHP_INT_MAX;
for ( $i = 1; $i <= $V ; $i ++)
{
for ( $j = 0; $j < $m ; $j ++)
if ( $coins [ $j ] <= $i )
{
$sub_res = $table [ $i - $coins [ $j ]];
if ( $sub_res != PHP_INT_MAX &&
$sub_res + 1 < $table [ $i ])
$table [ $i ] = $sub_res + 1;
}
}
if ( $table [ $V ] == PHP_INT_MAX)
return -1;
return $table [ $V ];
}
$coins = array (9, 6, 5, 1);
$m = sizeof( $coins );
$V = 11;
echo "Minimum coins required is " ,
minCoins( $coins , $m , $V );
?>
|
Output
Minimum coins required is 2
Time Complexity: O(m*V).
Auxiliary Space: O(V) because using extra space for array table
Feeling lost in the world of random DSA topics, wasting time without progress? It's time for a change! Join our DSA course, where we'll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 geeks!
Last Updated :
20 Oct, 2023
Like Article
Save Article