题目以下数组
示例 1:
输入: amount = 5, coins = [1, 2, 5]
输出: 4
解释: 有四种方式能够凑成总金额:
5=5
5=2+2+1
5=2+1+1+1
5=1+1+1+1+1
示例 2:
输入: amount = 3, coins = [2]
输出: 0
解释: 只用面额2的硬币不能凑成总金额3。
示例 3:
输入: amount = 10, coins = [10]
输出: 1
复制代码
解题思路以下: 采用动态规划 已知硬币面值coins[],用这些硬币凑成指定的金额amount。要求硬币个数最少。 设金额amount对应的最少硬币个数为:f(amount) 自上而下推,咱们能够这样想,金额amount对应的最少硬币数f(amount),确定是由另外一个金额加上一个已有的硬币面值来的。 能够得出: f(amount) = min(f(amount-coins[0]),f(amount-coins[1])…)+1 代码markdown
解题思路是从上向下,可是按照这个思路写代码时,会比较麻烦。能够考虑自下而上的方式。
初始化数组dp[amount+1],下标表示金额,值为最少硬币数。
dp[coins[0]]=dp[coins[i]]=…=1
由初始化后的数组,可推出以后全部的金额的最少硬币数。
复制代码
public static void main(String[] args) {
//采用动态规划
/**
* 已知硬币面值coins[],用这些硬币凑成指定的金额amount。要求硬币个数最少。
设金额amount对应的最少硬币个数为:f(amount)
自上而下推,咱们能够这样想,金额amount对应的最少硬币数f(amount),确定是由另外一个金额加上一个已有的硬币面值来的。
能够得出:
f(amount) = min(f(amount-coins[0]),f(amount-coins[1])…)+1
代码
解题思路是从上向下,可是按照这个思路写代码时,会比较麻烦。能够考虑自下而上的方式。
初始化数组dp[amount+1],下标表示金额,值为最少硬币数。
dp[coins[0]]=dp[coins[i]]=…=1
由初始化后的数组,可推出以后全部的金额的最少硬币数。
dp[i+coins[n]] = dp[i+coins[n]]>dp[i]+1?dp[i]+1:dp[i+coins[n]];
*/
int amount = 6;
int coins[] ={1,2,5};
//1*6 1*4+2 1*2+2*25*1
int result =new Solution().change(amount,coins);
System.out.println(result);
}
static class Solution{
public int change(int amount, int[] coins) {
int dp[] = new int[amount+1];
// 设置起始状态
dp[0] = 1;
for (int coin : coins) {
// 记录每添加一种面额的零钱,总金额j的变化
for (int j = 1; j <= amount; j++) {
if (j >= coin) {
// 在上一钟零钱状态的基础上增大
// 例如对于总额5,当只有面额为1的零钱时,只有一种可能 5x1
// 当加了面额为2的零钱时,除了原来的那一种可能外
// 还加上了组合了两块钱的状况,而总额为5是在总额为3的基础上加上两块钱来的
// 因此就加上此时总额为3的全部组合状况
dp[j] = dp[j] + dp[j - coin];
}
}
return dp[amount];
}
}
复制代码