一、题意
给你一个整数数组 coins ,表示不同面额的硬币;以及一个整数 amount ,表示总金额。
计算并返回可以凑成总金额所需的 最少的硬币个数 。如果没有任何一种硬币组合能组成总金额,返回 -1 。
你可以认为每种硬币的数量是无限的。
二、解法
解法:
动态规划
dp[i]表示金额为i的最少需要的硬币有多少个
dp[i]=min(dp[i],dp[i-coins[j]]+dp[coins[j]]),dp[i]>0。从1开始到i求dp[i],就可以将i之间的结果都求好,dp[i]即为结果。
时间复杂度:
O
(
n
S
)
O(nS)
O(nS)
空间复杂度:
O
(
S
)
O(S)
O(S)
三、代码
解法:
int coinChange(vector<int>& coins, int amount) {
if(amount==0){
return 0;
}
int n = coins.size();
vector<int> dp(amount+1,0);
for(int i=0;i<n;i++){
if(coins[i]<=amount){
dp[coins[i]]=1;
}
}
for(int i=1;i<=amount;i++){
for(int j=0;j<n;j++){
if(i-coins[j]>0&&dp[i-coins[j]]>0){
if(dp[i]>0){
dp[i] =min(dp[i],dp[coins[j]]+dp[i-coins[j]]);
}
else{
dp[i] = dp[coins[j]]+dp[i-coins[j]];
}
}
}
}
return dp[amount]>0?dp[amount]:-1;
}
四、总结
类似完全背包问题。
五、引用
[1] leetcode:322. Coin Change
[2] leetcode:322. Coin Change官方解法