情景一
给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 -1。
示例1
输入: coins = [1,2,5], amount = 3
输出: 3
解释: 11=5+5+1
示例2
输入: coins = [ 2], amount = 3
输出: -1
解释: 不存在
思路
动态规划:
f(x)=min{ f(x-ci) }+1 , i=1,2,3…n 这是递推公式,f(x)表示凑足x的钱最少的硬币数。其中f(0)=0
//通过动态规划来解决
func coinChange(coins []int, amount int) int {
if amount <0 || len(coins)==0 {
return -1
}
dp:=make([]int,amount+1)
dp[0] = 0
for i := 1yi; i < amount+1; i++ {
min := math.MaxInt64
for _, c := range coins {
j := i - c
if j >= 0 && dp[j] != -1 {
min = int(math.Min(float64(min), float64(dp[j])))
}
if min == math.MaxInt64 {
dp[i] = -1
} else {
dp[i] = min + 1
}
}
}
return dp[amount]
}
情景二
给定不同面额的硬币和一个总金额。写出函数来计算可以凑成总金额的硬币组合数。假设每一种面额的硬币有无限个。
注意: 你可以假设
0 <= amount (总金额) <= 5000
1 <= coin (硬币面额) <= 5000
硬币种类不超过500种
结果符合32位符号整数
示例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 = 3, coins = [2]
输出: 0
解释: 只用面额2的硬币不能凑成总金额3。
思路
动态规划:
f(x)=f(x-ci)+f(x) , i=1,2,3…n ,f(0)=1
//通过动态规划来解决
func coinChange2(coins []int, amount int) int {
if amount==0{
return 1
}
if amount <0 || len(coins)==0 {
return 0
}
dp:=make([]int,amount+1)
dp[0] =1
for i:=len(coins)-1;i>=0;i--{
for j:=0;j<=amount;j++{
if j-coins[i]>=0{
dp[j]=dp[j-coins[i]]+dp[j]
}
}
}
return dp[amount]
}