#include #include #include using namespace std; class Coins { // Step two: Memoization with a cache. public: vector v; vector cache; int M(int i); }; int Coins::M(int s) { int j, min; size_t i; /* Create the cache if this is our first call. Return the value from the cache if we've done this one already. */ if ((int) cache.size() <= s) cache.resize(s+1, -2); if (cache[s] != -2) return cache[s]; /* Base case -- if s is zero, we need zero coins. */ if (s == 0) { cache[s] = 0; return 0; } /* Otherwise, the code is nearly identical to the previous version. The only difference is that we put our answer into the cache. */ min = s+1; for (i = 0; i < v.size(); i++) { if (s >= v[i]) { j = M(s-v[i]) + 1; if (j != 0 && j < min) min = j; } } if (min == s+1) min = -1; cache[s] = min; return min; } int main(int argc, char **argv) { Coins c; int i; int sum; if (argc != 2) { cerr << "usage: coins s -- values on standard input\n"; exit(1); } sum = atoi(argv[1]); while (cin >> i) c.v.push_back(i); cout << c.M(sum) << endl; return 0; }