规范币集上的贪心找零
Greedy Coin Change on a Canonical Denomination Set
开始编码给定非负整数 amount 与一组互不相同的正整数面值 coin_denominations,调用方保证该集合是规范的(即降序贪心给出最少硬币数的最优解)。实现 solution(amount: int, coin_denominations: list[int]) -> list[list[int]],返回贪心分解结果——[coin, count] 列表,按面值降序排列,并省略 count == 0 的硬币。
算法就是把面值降序排好后扫一遍:每种 coin 取 count = remaining // coin,若 count > 0 就把 [coin, count] 加进结果,然后从 remaining 中减去 coin * count。因为面值集中含 1,循环结束时 remaining 必为 0。校验:coin_denominations 含重复元素抛 ValueError;coin_denominations 缺 1 抛 ValueError(否则某些 amount 无法表示)。
例如,solution(37, [1, 5, 10, 25, 100]) 返回 [[25, 1], [10, 1], [1, 2]]:37 // 25 = 1 余 12,12 // 10 = 1 余 2,2 // 5 = 0(跳过),2 // 1 = 2。自定义规范集 {1, 4, 16} 同理:solution(21, [1, 4, 16]) 返回 [[16, 1], [4, 1], [1, 1]]。退化情形单一面值就只能用 1 凑:solution(7, [1]) 返回 [[1, 7]]。空 amount 返回空:solution(0, [1, 5, 10, 25, 100]) 返回 []。
关于规范性的注意。 贪心并非对所有面值集合都最优。对 {1, 3, 4} 求 amount = 6:贪心给 4 + 1 + 1(3 枚),最优是 3 + 3(2 枚)。约束里写"币集是规范的",是把验证责任交给调用方;本函数不做规范性校验。规范集的常见例子有美元面值 {1, 5, 10, 25, 100}、以及任何"后一个币是前一个整数倍"的几何递增集(例如 {1, 4, 16})。
实践背景
执行算法里的现金分配子程序,本质上是同一个问题:给定要部署的目标名义量与一组允许的切片大小(clip size),把目标拆分成尽可能少的切片,让送往交易所的子单数最少(每条子单都有固定费用与每秒消息速率配额)。当切片菜单是规范的——典型如 {1, 10, 100, 1000} 股的粗到细阶梯——降序贪心就给出最少切片的最优拆分,时间线性。生产环境里的 sizing helper 在每次接到母单时都会调用这种例程,无需任何预计算。[coin, count] 这种形状正对应下游 child-order 生成器消费的 (clip_size, num_clips)。把它视为"在 sizing 规则确定阶梯之后,每种切片送多少条"这一问题的可执行内核即可。
约束条件
- `0 <= amount <= 10**4`
- `1 <= len(coin_denominations) <= 10`
- 每个 `coin > 0`。`coin_denominations` 出现重复元素抛 `ValueError`。
- `coin_denominations` 中必须包含 `1`(保证任意 amount 都可表示),否则抛 `ValueError`。
- 调用方保证币集是**规范的**(贪心最优)。参考实现不校验规范性。
- 返回 `list[list[int]]`,每项 `[coin, count]`,按**面值降序**排列,且省略 `count == 0` 的硬币。`amount = 0` 时返回 `[]`。
样例
Case 1 · statement-example: US set 37 cents
输入: [37,[1,5,10,25,100]]
期望: [[25,1],[10,1],[1,2]]
降序贪心:37 // 25 = 1 余 12;12 // 10 = 1 余 2;2 // 5 = 0;2 // 1 = 2。略去 0 计数后输出 [[25,1],[10,1],[1,2]]。
Case 2 · statement-example: amount=0 returns empty list
输入: [0,[1,5,10,25,100]]
期望: []
amount=0 时无需任何硬币,按零计数过滤后返回空列表 []。
Case 3 · statement-example: custom canonical {1, 4, 16} for 21
输入: [21,[1,4,16]]
期望: [[16,1],[4,1],[1,1]]
{1, 4, 16} 是规范集合(每个币是前一个的整数倍):21 = 16 + 4 + 1,按降序输出 [[16,1],[4,1],[1,1]]。
最近提交
还没有提交记录。
编码区
实现 solution(...)。本地运行当前支持 Python 可见样例;服务端提交会运行可见样例和隐藏测试。
默认展示公开样例。点击「运行样例」后会在这里显示实际输出;点击「提交评测」会进入隐藏测试。
Case 1 · statement-example: US set 37 cents
输入: [37,[1,5,10,25,100]]
期望: [[25,1],[10,1],[1,2]]
降序贪心:37 // 25 = 1 余 12;12 // 10 = 1 余 2;2 // 5 = 0;2 // 1 = 2。略去 0 计数后输出 [[25,1],[10,1],[1,2]]。
Case 2 · statement-example: amount=0 returns empty list
输入: [0,[1,5,10,25,100]]
期望: []
amount=0 时无需任何硬币,按零计数过滤后返回空列表 []。
Case 3 · statement-example: custom canonical {1, 4, 16} for 21
输入: [21,[1,4,16]]
期望: [[16,1],[4,1],[1,1]]
{1, 4, 16} 是规范集合(每个币是前一个的整数倍):21 = 16 + 4 + 1,按降序输出 [[16,1],[4,1],[1,1]]。