Actually, this problem could use greedy algorithm instead of dynamic programming and greedy algorithm is much faster. The basic idea is sort the coins array from the largest to the smallest and then try coin with the largest value until the total value is larger than "amount". If the total value cannot be equal to "amount" and then go back to the upper layer and try the second largest one... So the optimal answer always comes first.
class Solution { public: int coinChange(vector<int>& coins, int amount) { sort(coins.begin(), coins.end(), greater<int>()); int res = amount+1; ccHelper(amount, coins, 0, 0, res); return res==amount+1? -1: res; } void ccHelper(int amount, vector<int>&coins, int start, int step, int& res) { if (step+ceil(amount*1.0/coins[start])>=res) return; if (amount==0) {res=step; return;} for (int i=start; i<coins.size(); i++) { if (coins[i]<=amount) ccHelper(amount-coins[i], coins, i, step+1, res); } } };
"greater" on the 4th line is an interesting and useful class. Please pay attention to it.