DC娱乐网

工资袋问题:用贪心算法算出凑满金额所需的最少货币数量

用最少的钞票数量凑出所需的金额,有一个专门的名称,叫贪心算法。案例:计算下图 1 中的金额所需的最小数量的钞票组合,支持

用最少的钞票数量凑出所需的金额,有一个专门的名称,叫贪心算法。

案例:

计算下图 1 中的金额所需的最小数量的钞票组合,支持人民币标准面额为 100、50、20、10、5、2、1、0.5、0.1、0.05、0.01。

效果如下图 2 所示。

解决方案:

1. 按 Alt+F11 打开 VBE --> 输入以下代码:

Sub CalculateExactCombo()

Dim amount As Currency

Dim result As String

Dim denominations() As Variant

Dim counts() As Integer

Dim i As Integer

' 定义面额(元+分,按从大到小排序)

denominations = Array(100, 50, 20, 10, 5, 2, 1, 0.5, 0.1, 0.05, 0.01)

ReDim counts(LBound(denominations) To UBound(denominations))

' 获取金额并验证

amount = Round(Range("A2").Value, 2)

If amount <= 0 Then

MsgBox "金额必须大于0", vbExclamation

Exit Sub

End If

' 计算各面额数量

For i = LBound(denominations) To UBound(denominations)

If amount >= denominations(i) Then

counts(i) = Int(amount / denominations(i))

amount = Round(amount - (counts(i) * denominations(i)), 2)

End If

Next i

' 验证是否完全凑齐

If amount > 0 Then

MsgBox "警告:剩余 " & amount & " 元无法分配", vbExclamation

End If

' 生成结果

result = vbCrLf

For i = LBound(denominations) To UBound(denominations)

If counts(i) > 0 Then

result = result & Format(denominations(i), "0.00") & "元:" & counts(i) & "张" & vbCrLf

End If

Next i

' 输出到B2单元格

Range("B2").Value = result

Range("B2").Columns.AutoFit

End Sub

2. 点击“运行”按钮运行代码。

结果如下。

3. 更改金额后再次运行代码,得到以下结果。