题目描述
给定不同面额的硬币 coins 和一个总金额
amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 -1。示例 1:
输入: coins = [1, 2, 5], amount = 11 输出: 3 解释: 11 = 5 + 5 + 1
解题思路:
- dp[i]代表金额i的最优解,即使用最少张数,使用dp[1]~dp[amount]存储1-amount金额的最优解
- 实例中金额分别1,2,5.所以dp[1],dp[2],dp[5]都是等于1
- 金额i最优解可以由i-1与dp[1],i-2与dp[2],i-5与dp[5]转移得到,所以dp[i]的最优解就是dp[i-1]+1,dp[i-2]+1,dp[i-5]+1中最小的。
- 转移方程dp[i]=min(dp[i-coins[j]]+1)
- 初始化dp[0]=0
class Solution {
public int coinChange(int[] coins, int amount) {
int[] dp=new int[amount+1];
for(int i=0;i<=amount;i++){
dp[i]=-1;//初始化dp[],用-1标记为不可达
}
dp[0]=0;//初始化边界条件
for(int i=1;i<=amount;i++){
for(int j=0;j<coins.length;j++){
if(i-coins[j]>=0&&dp[i-coins[j]]!=-1){//当前金额-面值>0&&前面差值可达、可表示
if(dp[i]==-1||dp[i]>dp[i-coins[j]])//dp[i]没被更新过或者dp[i]有更好的解
dp[i]=dp[i-coins[j]]+1;
}
}
}
return dp[amount];
}
}