目录
冰激凌甜点成本最接近目标值 — 题解与详解
题目描述
你想自制冰激凌甜点。共有 n 种冰激凌基料(baseCosts),以及 m 种配料(toppingCosts)可供选择。制作甜点需满足以下规则:
- 必须选择 一种 冰激凌基料。
- 可以添加 零个或多个 配料。
- 每种配料最多可以添加 两份。
- 希望甜点的总成本尽可能接近给定的目标价格 target。
- 如果有多个方案同样接近目标价格,选择成本较低的方案。
给定:
baseCosts: 一个长度为 n 的整数数组,表示每种冰激凌基料价格。toppingCosts: 一个长度为 m 的整数数组,表示每种配料价格。target: 目标价格。
返回最接近 target 的甜点成本。
题目分析
这是一个典型的组合枚举问题,我们需要从基料中选一种,然后从配料中选0~2份,组成各种配料组合,求其总成本最接近目标。
关键点:
- 必选一个基料,基料数目不大,直接枚举。
- 配料每种可选0、1或2份,枚举配料组合时每种配料的选项为3种。
- 目标是求和与目标值
target差的绝对值最小。 - 若多个方案同样接近,则选成本较低的方案。
解题方法
1. 暴力递归(深度优先搜索)
我们对基料进行遍历,然后对配料进行深度优先搜索,枚举每种配料选0、1、2份,递归计算总成本。
- 递归参数:当前配料索引
i和当前成本cost。 - 递归终止条件:
i == len(toppingCosts),更新最优解。 - 递归分支:不选当前配料,选1份,选2份。
每次更新答案时,判断当前成本与目标的距离,若更近或距离相同但成本更低,则更新答案。
2. 代码实现示例(Python)
from typing import List
class Solution:
def closestCost(self, baseCosts: List[int], toppingCosts: List[int], target: int) -> int:
best = None
def update(cost):
nonlocal best
if best is None or abs(cost - target) < abs(best - target) or (abs(cost - target) == abs(best - target) and cost < best):
best = cost
def dfs(i, cost):
if i == len(toppingCosts):
update(cost)
return
# 不选当前配料
dfs(i + 1, cost)
# 选1份
dfs(i + 1, cost + toppingCosts[i])
# 选2份
dfs(i + 1, cost + 2 * toppingCosts[i])
for base in baseCosts:
dfs(0, base)
return best
复杂度分析
- 基料数为 n,配料数为 m。
- 对每个基料,配料有3种选择(0/1/2份),组合数量为 3^m。
- 总时间复杂度约为 O(n * 3^m)。
- 对于小m(如m ≤ 10),此方案可行。
示例说明
示例
baseCosts = [1, 7]
toppingCosts = [3, 4]
target = 10
- 基料选1,配料可选0~2份:
-
- 不选配料,总成本 = 1
- 选1份配料3,总成本 = 4
- 选2份配料3,总成本 = 7
- 选1份配料4,总成本 = 5
- 选2份配料4,总成本 = 9
- 选1份配料3 + 1份配料4,总成本 = 8
- … 等等
- 基料选7,配料同理:
-
- 不选配料,总成本 = 7
- 选1份配料3,总成本 = 10 ← 恰好命中目标
- 选2份配料3,总成本 = 13
- 选1份配料4,总成本 = 11
- … 等等
通过枚举,可以发现最接近10的成本是10(基料7+1份配料3),返回10。
总结与扩展
- 本题关键在于合理枚举配料的选择。
- 利用递归遍历所有配料状态,保证不漏选方案。
- 由于配料选项固定(0/1/2份),枚举量是有限的。
- 可在递归中加剪枝(如当前成本已远超target且不可能更优时剪枝),提高效率。
- 也可尝试用动态规划思路,但考虑到每种配料最多选两份,递归实现较为简洁。
如果配料数量非常大,需优化算法或使用其他近似策略。

被折叠的 条评论
为什么被折叠?



