情景一

  • 描述

给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 -1。

示例1
输入: coins = [1,2,5], amount = 3
输出: 3
解释: 11=5+5+1
示例2
输入: coins = [ 2], amount = 3
输出: -1 
解释: 不存在
  • go实现

思路

动态规划:
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。
  • go实现

思路

动态规划:
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]
}