题目描述
给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 -1。
示例 1:
输入: coins = [1, 2, 5], amount = 11
输出: 3
解释: 11 = 5 + 5 + 1
示例 2:
输入: coins = [2], amount = 3
输出: -1
说明:
你可以认为每种硬币的数量是无限的。
思路参考
代码
class Solution {
vector<int> memo;
public:
int dp(vector<int>& coins,int rem)
{
if(rem<0) return -1;//剩余待计算金额少于0时,多加了一枚
if(rem==0) return 0;
if(memo[rem-1] != 0) return memo[rem-1];//剪枝优化,减少计算
int Min = INT_MAX;//记录最少的硬币数
for(int coin:coins)
{
int res = dp(coins, rem - coin);
if(res >= 0 && res < Min)
Min = res + 1;
}
memo[rem-1] = Min == INT_MAX? -1 : Min;
return memo[rem-1];
}
int coinChange(vector<int>& coins, int amount) {
if(amount<1) return 0;//若0元,返回0个硬币
memo.resize(amount);//剪枝,用于减少子问题的重复计算
return dp(coins,amount);//自顶向下的动态规划
}
};