淘先锋技术网

首页 1 2 3 4 5 6 7

问题:给你 k 种面值的硬币,面值分别为 c1, c2 … ck,每种硬币的数量无限,
再给一个总金额 amount,问你最少需要几枚硬币凑出这个金额,
如果不可能凑出,算法返回 -1

比如说 k = 3,面值分别为 2,5,10,总金额 amount = 11。那么最少需要 4枚硬币凑出,即 11 = 5 + 2 + 2+2。
我们先列出一组结果值
0 小于2 结果为0
1 小于2 结果为0
2 为面值金额里面的倍数 结果为1
3 为1的结果然后加上最小面额2 但是1为0 所以为0
4 2的结果加上最小面额 1+1 =2
5 为1
6 4的结果+1 为3

解决思路点
1.每次都以最小步长为基础找出对应的值,当找到前面的结果为0或者为初始化值的时候,并且不被当前面值整除,说明没有找到对应的值
2.当前值为当前的货币面值-对应货币面值的列值 如: 6 4的结果+1 为3
3.当结果为最大值或者为0时,不能找到

func CoinChange(coins []int, amount int) int {
	var dp []int
	for i:=0;i<=amount+1;i++{
		if i ==0 {
			dp = append(dp,0)
		}else{
			dp = append(dp,amount+1)
		}
	}
	for i:=0;i<len(dp);i++{
		for _,coin:= range coins{
			if i-coin <0 {
				continue
			}
			if dp[i-coin] != amount+1 {
				if dp[i] > 1+ dp[i-coin]  {
					if dp[i-coin]!=0 {
						tmp:=0
						if i%coin ==0 {
							tmp =i/coin
						}
						if tmp!=0&& tmp<1+ dp[i-coin] {
							dp[i] = tmp
						}else{
							dp[i] = 1+ dp[i-coin]
						}
					}else{
						if i%coin ==0 {
							dp[i] =i/coin
						}
					}
				}
			}else{
				continue
			}
		}
	}
	if dp[amount] == amount+1 {
		return -1
	}else{
		return dp[amount]
	}
}

func main() {
	coins:= []int{2,5,10}
	amount:=33
	CoinChange(coins,amount)
}