题目描述
用coins = [1, 2, 5], amount = 11举例
组成11的硬币数,考虑最后一枚硬币是1、2、5,可以分3种情况:
- 最后一枚硬币是1元:num1 = 【组成10的最小硬币数】+ 1(1枚1元硬币)
- 最后一枚硬币是2元:num2 = 【组成9的最小硬币数】+ 1(1枚2元硬币)
- 最后一枚硬币是5元:num3 = 【组成6的最小硬币数】+ 1(1枚5元硬币)
综合上述3种情况,组成11的最少硬币数就是min(num1, num2, num3)
动态规划思想在于先解决小问题,解决大问题的时候直接使用小问题的结论进行解决。为此我们有一个for循环,当前兑换金额cur从1到最终的amount递增,先考虑总金额较小时,需要最少的硬币数
int coinChange(vector<int>& coins, int amount) {
vector<int> dp(amount+1 , -1);
dp[0] = 0;//0元钱最少需要0个硬币
for(int cur = 1; cur <= amount; cur++){
dp[cur] = amount + 1; //只要有面值为1的硬币,就可以兑换成功,最多使用amount个硬币。否则将硬币数量设为amount + 1 表示当前金额cur无法兑换
for(int coin : coins){
//此循环完成后就相当于上述解析种的min(num1, num2, num3)完成
if(cur >= coin){
dp[cur] = dp[cur-coin] + 1 < dp[cur] ? dp[cur-coin] + 1 : dp[cur];
}
}
}
return dp[amount] == amount + 1 ? -1 : dp[amount];
}