|
|
|
|
How can we:
|
|
Fact:
|
|
|
Notice that:
|
|
findM( j, (v1,v2, ..., vC) )
{
// Let us not worry about the base cases for now....
/* ========================================
Divide and conquer procedure to find
min. # coins to change for $j
======================================== */
/* ---------------------------------------------
Suppose last coin used has value v1
--------------------------------------------- */
if ( j >= v1 )
{
sol1 = findM( j-v1, (v1,v2, ..., vC) );
mySol1 = sol1 + 1; // I will one more coin to make change for $j
}
/* ---------------------------------------------
Suppose last coin used has value v2
--------------------------------------------- */
if ( j >= v2 )
{
sol2 = findM( j-v2, (v1,v2, ..., vC) );
mySol2 = sol2 + 1; // I will need one more coin to make change for $j
}
.... (and so on)
/* ---------------------------------------------
Suppose last coin used has value vC
--------------------------------------------- */
if ( j >= vC )
{
solC = findM( j-vC, (v1,v2, ..., vC) );
mySolC = solC + 1; // I will need one more coin to make change for $j
}
/* ========================================================
The smallest # coins needed to make change for $j
======================================================== */
myFinalSol = min ( mySol1, MySol2, ...., mySolC );
// Note: use only the valid value mySoli !!!
return ( myFinalSol );
}
|
|
|
In other words:
M(0) = 0
|
findM( j, (v1,v2, ..., vC) )
{
/* ---------------------------
Base case
--------------------------- */
if ( j == 0 )
{
return(0);
}
/* ========================================
Divide and conquer procedure to find
min. # coins to change for $j
======================================== */
/* ---------------------------------------------
Suppose last coin used has value v1
--------------------------------------------- */
if ( j >= v1 )
{
sol1 = findM( j-v1, (v1,v2, ..., vC) );
mySol1 = sol1 + 1; // I will one more coin to make change for $j
}
/* ---------------------------------------------
Suppose last coin used has value v2
--------------------------------------------- */
if ( j >= v2 )
{
sol2 = findM( j-v2, (v1,v2, ..., vC) );
mySol2 = sol2 + 1; // I will need one more coin to make change for $j
}
.... (and so on)
/* ---------------------------------------------
Suppose last coin used has value vC
--------------------------------------------- */
if ( j >= vC )
{
solC = findM( j-vC, (v1,v2, ..., vC) );
mySolC = solC + 1; // I will need one more coin to make change for $j
}
/* ========================================================
The smallest # coins needed to make change for $j
======================================================== */
myFinalSol = min ( mySol1, MySol2, ...., mySolC );
// Note: use only the valid value mySoli !!!
return ( myFinalSol ); // Return answer
}
|
static int M(int j, int[] v)
{
int[] sol, mySol;
int myFinalSol;
int k;
sol = new int[v.length];
mySol = new int[v.length];
/* ---------------------------
Base cases
--------------------------- */
if ( j == 0 )
{
return(0);
}
/* ==================================================
Initialize mySol[]
================================================== */
for ( k = 0; k < v.length; k++ )
mySol[k] = -1; // -1 means: no solution
/* --------------------------------------------------------
Try every denomination k = 1,2,..,C for the last coin
-------------------------------------------------------- */
for ( k = 0; k < v.length; k++ )
{
/* --------------------------------------------
Check if we can use the k-th denomination
-------------------------------------------- */
if ( v[k] <= j )
{
/* ------------------------
Divide step
------------------------ */
sol[k] = M(j - v[k], v); // Use coin v[k] as last coin
mySol[k] = sol[k] + 1; // Solution to make change for $j
}
}
/* --------------------------------------------------------
Find the minimum for ALL mySol[...] values
Note: -1 means do NOT use !
-------------------------------------------------------- */
myFinalSol = -1;
for ( k = 0; k < v.length; k++ )
{
if ( mySol[k] >= 0 /* Don't use -1 values */ )
{
if ( myFinalSol == -1 || mySol[k] < myFinalSol )
myFinalSol = mySol[k];
}
}
return(myFinalSol); // Return best solution
}
|
How to run the program:
|
The reason for this slowness is:
|
|
|
static int findM(int Am, int v[])
{
int[] M;
int[] sol, mySol;
int j, k, min;
M = new int[Am+1]; // Store results
sol = new int[v.length];
mySol = new int[v.length];
/* ---------------------------
Base case
--------------------------- */
M[0] = 0; // 0 coins needed to make change for $0
/* ---------------------------------------------------
The other cases (starting from 1 to M.length - 1)
Follow direction of data flow !
--------------------------------------------------- */
for ( j = 1; j <= Am; j++ )
{
/* ============================================
Find min # coin to make change for $j
============================================ */
for ( k = 0; k < v.length; k++ )
mySol[k] = -1; // Initialize mySol[]
/* --------------------------------------------------------
Try every denomination k = 1,2,..,C for the last coin
-------------------------------------------------------- */
for ( k = 0; k < v.length; k++ )
{
/* --------------------------------------------
Check if we can use the k-th denomination
-------------------------------------------- */
if ( v[k] <= j )
{
/* ------------------------
Divide step
------------------------ */
sol[k] = M[j - v[k]]; // Use coin v[k] as last coin
mySol[k] = sol[k] + 1; // Solution to make change for $j
}
}
/* --------------------------------------------------------
Find the minimum of all mySol[...]
-------------------------------------------------------- */
M[j] = -1;
for ( k = 0; k < v.length; k++ )
{
if ( mySol[k] > 0 )
{
if ( M[j] == -1 || mySol[k] < M[j] )
M[j] = mySol[k];
}
}
}
return( M[Am] ); // Min # coins to change $Am
}
|
How to run the program:
|
Note:
|
|
Running time: O(CN)
(C = # denominations)
(N = amount to make change for)