leetcode原题链接:零钱兑换
上一篇:HOT84-完全平方数
下一篇:HOT86-单词拆分
题目描述
给你一个整数数组 coins
,表示不同面额的硬币;以及一个整数 amount
,表示总金额。
计算并返回可以凑成总金额所需的 最少的硬币个数 。如果没有任何一种硬币组合能组成总金额,返回 -1
。你可以认为每种硬币的数量是无限的。
示例 1:
输入:coins =[1, 2, 5]
, amount =11
输出:3
解释:11 = 5 + 5 + 1
示例 2:
输入:coins =[2]
, amount =3
输出:-1
示例 3:
输入:coins = [1], amount = 0 输出:0
解题方法:动态规划
1. 问题定义: dp[n]表示总金额为n 对应的最少硬币
2. 初始化: dp[0] = 0;
3. 状态转移方程: min_count = std::min(min_count, dp[i - coin]); dp[i] = min_count + 1
4. 结果返回:dp[n]
C++代码
#include <iostream>
#include <vector>
#include <climits> // INT_MAX
class Solution {
public:
int coinChange(std::vector<int>& coins, int amount) {
int n = coins.size();
if (n == 0) {
return -1;
}
// 1. 问题定义: dp[k]表示总金额为k 对应的最少硬币
const int MAX_NUM = amount + 1;
std::vector<int> dp(amount + 1, MAX_NUM);
// 2. 初始化
dp[0] = 0;
// 3. 递归顺序: 从小到达求解
for (int i = 1; i <= amount; i++) {
//为每一个数字求解最小货币数
int min_count = MAX_NUM;
for (auto coin : coins) {
if (coin <= i) {
// 4. 状态转移方程
min_count = std::min(min_count, dp[i - coin]);
}
}
dp[i] = min_count + 1; //如果dp[i]没有求到解,将会是一个大于amount的数字
}
// 4. 求解
return dp[amount] > amount ? -1 : dp[amount];
}
};