LeetCode-322-零钱兑换
LeetCode-322-零钱兑换
题目
给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 -1.
示例 1:
输入: coins = [1, 2, 5], amount = 11
输出: 3
解释: 11 = 5 + 5 + 1
示例 2:
输入: coins = [2], amount = 3
输出: -1
思路
第一次看到这道题的时候,没有设定好状态转移方程的自变量,就是dp[i]的i值一开始没找好,所以想了半天没有思路;
过了一天后发现,可以用i值表示金额,即一块钱一块钱的加上来,每次都找到花费硬币最少的哪个方案即可:
\[dp[i]=min(dp[i-1]+1)
\]
想通了之后发现特别简单,但是没有设定好方程之前就是做不出来。
最后结果效果不是很好,然后我发现coins排序后,可以在一定程度剪枝,提升了一点点,代码如下:
代码
class Solution {
public:
const int INFTY = (1<<10);
int coinChange(vector<int>& coins, int amount) {
vector<int> dp;
dp.push_back(0);
sort(coins.begin(), coins.end());
for (int i=1; i<amount+1; i++)
{
int num = INFTY;
for (const int&coin:coins)
{
if (i-coin < 0)
break;
if (dp[i-coin] < 0)
continue;
num = min(num, dp[i-coin]);
}
dp.push_back((num==INFTY?-1:num+1));
}
return dp.back();
}
};