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