题目描述:
给定一组不同面额的硬币(保证包含面额 1
且相邻面额是倍数关系),和一个目标金额 amount
,要求你找出最少的硬币数目,使得硬币的总金额等于目标金额。
要求:
-1
。输入格式:
n
,表示硬币的数量。1 ≤ n
≤ 20n
个整数,表示硬币的面额coins,保证每个面额都大于0且相邻的面额满足倍数关系,且包含面额 1
。1 ≤ coins[i]
≤ 109amount
,表示目标金额。1 ≤ amount
≤ 109输出格式:
-1
。示例:
输入:
5
1 5 10 20 100
66
输出:
5
说明:
20
+ 20
+ 20
+ 5
+ 1
,总金额为 11
,硬币数目为 3
。5
。给定一组硬币的面额,其中包含面额 1
且相邻面额满足倍数关系,和一个目标金额 amount
。要求找出最少的硬币数目,使得硬币的总金额等于目标金额。如果无法组合成目标金额,返回 -1
。
该问题可以通过 贪心算法 来解决。因为题目给定的硬币面额满足倍数关系,贪心算法在这种情况下是最优的。具体来说,贪心策略是优先选择面额较大的硬币,这样能尽可能少地使用硬币来达到目标金额。
amount
减为零时,表示已经找到了解决方案;如果遍历所有硬币后仍然无法达到目标金额,则返回 -1
。反证法
def minCoins(coins, amount):
# 将硬币按面额从大到小排序
coins.sort(reverse=True)
# 初始化硬币数目
coin_count = 0
# 遍历硬币,尝试从大到小使用硬币
for coin in coins:
if amount == 0:
break
# 使用尽可能多的当前硬币
coin_count += amount // coin
amount %= coin # 更新剩余金额
# 如果amount变为0,说明找到了最小硬币数
if amount == 0:
return coin_count
else:
return -1 # 如果无法组合成目标金额,返回-1
# 输入处理部分
n = int(input()) # 硬币数量
coins = list(map(int, input().split())) # 硬币面额
amount = int(input()) # 目标金额
# 输出最少硬币数
print(minCoins(coins, amount))