Solution: The Greedy algorithm only works in special cases, but we're trying to find the ultimate, smallest and fast solution.
The goal is to check all possibilities, which can take a lot of time, if we don't use memoization. The solution below is a recursive function with two arguments:
- int[] k - table of coins (1, 3, 5) ordered ascending
- int val - the value we wish to solve
public static Hashtable<Integer, Integer> solved = new Hashtable<Integer, Integer>(); public static int kovanci(int[] k, int val) { // we've reached the end of recursion - a leaf // if the value is less than zero it means that the current combination is not solvable // if the value is zero, it means it is solvable if (val <= 0) return val; // for as many coins try to decrease the value for the coin value // and try to solve the smaller problem int min = -1; //default: if it's not solvable for (int i = k.length - 1; i >= 0; i--) { // if the coin k[i] exists in the solution, it means the solution is // solutions(value - coin_value) + 1 // eg. we have coins: 1, 3, 5 and the value is 11 // if the coin 5 exists in the solution, try to solve the problem for value 11-5 = 6 // the solution is smaller_solution + 1 int newVal = val - k[i]; int r; // dynamic programming - memoization // if we already have the minimum for the new value, fetch it (with time complexity O(1)), // so that we don't recursively re-solve the problem and waste time if (solved.get(newVal) != null) { //solution = smaller_sollution + 1 r = solved.get(newVal) + 1; } else { //try to solve the smaller problem r = kovanci(k, newVal); //if the solution is valid, the new solution is smaller_solution + 1 if (r >= 0) r++; //else, keep the negative value - it means that it's not valid //eg: coins 3, 5, value 11 is not solvable, the solution is -1 } // from all of the solutions, get the minimum value // and skip invalid solutions ( less than zero ) if ((r > 0) && (min == -1 || r < min)) { min = r; } } // dynamic programming - memoization // once we do get the smallest possible solution, save it for later use // it saves A LOT of time and useless work, that's already been done solved.put(val, min); return min; }
1 comment:
Hello,
I just found your website and the implementation that of the algorithm I've been looking for a while. I was wondering how to implement it in C++ using only 1d array of integers and memoization that it would always go back only twice I mean checking the last 2 values that have been put into the array. If you'd be so nice to explain how to implement it in C++ using 1d array I'd be grateful. Thanks
Post a Comment