Engee 文档
Notebook

兑换硬币的方法

让我们考虑一个算法的实现,用于计算使用指定硬币面额交换给定金额的方式的数量。

导言

用于计算交换硬币的方式数量的算法解决了计算使用不同硬币面额表示给定金额的货币的方式数量的问题。 这是一个经典的动态规划问题,经常用于组合学和经济模型。

功能 changes

功能 changes 计算更改给定金额的方法数(amount)使用可用的硬币面额(coins).

参数:

  • amount:整数-要交换的金额
  • coins:整数数组-可用硬币的面额

申报表:

-类型的数字 Int128 -交换方法的数量

In [ ]:
function changes(amount::Int, coins::Array{Int})::Int128
    # 创建一个数组来存储将每个金额从0更改为金额的方法的数量
    # 索引从1开始,因此数组的大小为1+1
    ways = zeros(Int128, amount + 1)

    # 对于0的数量,有一种方法-不使用任何硬币。
    ways[1] = 1

    # 我们通过每个硬币
    for coin in coins
        # 从"硬币"到"金额`的每个金额
        for j in coin+1:amount+1
            # 更新方式数量:添加获取金额的方式(j-coin)
            ways[j] += ways[j - coin]
        end
    end

    # 返回更改金额"金额`的方法数目
    return ways[amount + 1]
end
Out[0]:
changes (generic function with 1 method)
In [ ]:
# 使用函数的示例

@show changes(100, [1, 2, 5, 10]);       # 使用1,2,5,10卢布硬币交换100卢布
@show changes(100_000, [1, 5, 10]);    # 兑换10万卢布
changes(100, [1, 2, 5, 10]) = 2156
changes(100000, [1, 5, 10]) = 100020001

主要部分

程序做什么?

该程序计算多少种不同的方式一定数量的钱可以使用一组有限的硬币进行交换。

例如,有多少种面值为1,2,5和10的硬币组合可以获得高达100卢布的任何金额?

它是如何工作的? 分步说明:

步骤1:初始化

我们正在创建一个数组 ways,在哪里 ways[i] 它将包含数量的方式来弥补金额。 (i - 1) (由于从unity索引到Julia)。

在开始时,我们假设有一种方法可以获得金额。 0(取0枚硬币):

步骤2:动态更新值

对于每个硬币,我们按顺序更新值。 ways. 如果我们有一个面值为5卢布的硬币,那么:

-5的金额可以兑换为0+5→增加 ways[6]ways[1]
-10的总和为5+5→增加 ways[11]ways[6] 等。

步骤3:为什么这个循环顺序很重要?

周期通过硬币运行,并在它通过金额。 此顺序确保我们不会将相同的硬币组合计数两次(例如,5+10和10+5计数为相同的方式)。

程序的结果

程序通过宏输出函数调用的结果 @show,自动打印表达式及其值。

结论

我们已经审查了计算货币兑换方式的算法的实现。 该算法广泛应用于支付系统的组合、金融建模和测试等问题。

该示例是使用[Rosetta代码]的材料开发的(https://rosettacode.org/wiki/Count_the_coins