最优硬币组合问题 | 豆包MarsCode AI 刷题

103 阅读4分钟

问题描述

小C有多种不同面值的硬币,每种硬币的数量是无限的。他希望知道,如何使用最少数量的硬币,凑出给定的总金额N。小C对硬币的组合方式很感兴趣,但他更希望在满足总金额的同时,使用的硬币数量尽可能少。

例如:小C有三种硬币,面值分别为 125。他需要凑出总金额为 18。一种最优的方案是使用三个 5 面值的硬币,一个 2 面值的硬币和一个 1 面值的硬币,总共五个硬币。


测试样例

样例1:

输入:coins = [1, 2, 5], amount = 18
输出:[5, 5, 5, 2, 1]

样例2:

输入:coins = [1, 3, 4], amount = 6
输出:[3, 3]

样例3:

输入:coins = [5], amount = 10
输出:[5, 5]

问题理解

你需要找到一种方法,使用最少数量的硬币来凑出给定的总金额 N。每种硬币的面值和数量都是无限的。

数据结构选择

  1. 动态规划数组 dp

    • dp[i] 表示凑出金额 i 所需的最少硬币数量。
    • dp[0] 初始化为 0,因为凑出金额 0 不需要任何硬币。

算法步骤

  1. 初始化

    • 创建一个长度为 amount + 1 的数组 dp,所有元素初始化为 None
    • dp[0] 初始化为 0
  2. 状态转移

    • 对于每个硬币面值 coin,遍历从 coin 到 amount 的所有金额 i
    • 如果 dp[i - coin] 不是 None,说明可以通过使用 coin 来凑出金额 i
    • 更新 dp[i] 为 dp[i - coin] + 1,如果当前 dp[i] 是 None 或者新的组合更少。
  3. 结果

    • 最终 dp[amount] 就是凑出金额 amount 所需的最少硬币数量。

注意

  • 这个代码框架只计算了最少硬币数量,并没有记录具体的硬币组合。如果你需要记录具体的硬币组合,可以在 dp 数组中存储具体的硬币列表,并在更新时进行相应的操作。

代码实现

def solution(coins, amount):
    # 创建一个数组dp,其中每个元素初始化为None
    dp = [None] * (amount + 1)
    dp[0] = []  # 0金额需要0个硬币,因此初始化为空列表

    for coin in coins:
        for i in range(coin, amount + 1):
            if dp[i - coin] is not None:  # 如果i - coin的组合存在
                # 如果当前位置为空或者新的组合更短
                if dp[i] is None or len(dp[i - coin]) + 1 < len(dp[i]):
                    dp[i] = dp[i - coin] + [coin]  # 更新组合

    # 如果找到结果,则按降序返回
    return sorted(dp[amount], reverse=True) if dp[amount] is not None else []

# 测试案例
print(solution([1, 2, 5], 18))  # 输出: [5, 5, 5, 2, 1](降序排列)
print(solution([1, 3, 4], 6))   # 输出: [4, 2](降序排列)
print(solution([5], 10))         # 输出: [5, 5](降序排列)

# 测试案例
print(solution([1, 2, 5], 18))  # 输出: 预期可能为[some combination that sums to 18]


if __name__ == "__main__":
    # Add your test cases here

    print(solution([1, 2, 5], 18) == [5, 5, 5, 2, 1])

我们就成功通过了本题🤩

本次我们通过《最优硬币组合问题》这道题目的解决过程展示了豆包MarsCode AI刷题平台的几个显著亮点:

  1. 算法推荐与指导:当用户在解决问题时遇到瓶颈,例如不知道如何有效统计特定范围内的二进制数中1的个数之和时,AI能够提供具体的算法建议,并给出详细的算法流程、伪代码及实现代码,极大地降低了学习和解决问题的门槛。
  2. 多语言支持与代码转换:虽然豆包MarsCode AI刷题平台可能最初只提供了某些编程语言的支持,但它具备强大的跨语言代码转换功能,可以将用户的C++代码转换成Java或Python等其他语言的等效代码。这一特性对于那些需要在不同语言环境间切换的开发者来说非常有用,确保了用户能够在任何平台上顺利提交解决方案。
  3. 实践性与即时反馈:通过实际编写代码并测试示例输入输出,用户可以在提交之前验证自己的解答是否正确。这种即时的反馈机制有助于加深理解,及时调整错误,提高学习效率。

综上所述,豆包MarsCode AI刷题平台具有精准的算法指导、灵活的多语言支持以及即时的实践反馈,为用户提供了一个高效、便捷且富有成效的学习环境。

好了,那么我们这一次的解析就到这里,后面会给大家展示豆包MarsCode AI刷题的更多功能