1774. 最接近目标价格的甜点成本
你打算做甜点,现在需要购买配料。目前共有 n
种冰激凌基料和 m
种配料可供选购。而制作甜点需要遵循以下几条规则:
给你以下三个输入:
baseCosts
,一个长度为 n
的整数数组,其中每个 baseCosts[i]
表示第 i
种冰激凌基料的价格。toppingCosts
,一个长度为 m
的整数数组,其中每个 toppingCosts[i]
表示 一份 第 i
种冰激凌配料的价格。target
,一个整数,表示你制作甜点的目标价格。你希望自己做的甜点总成本尽可能接近目标价格 target
。
返回最接近 target
的甜点成本。如果有多种方案,返回 成本相对较低 的一种。
示例 1:
输入:baseCosts = [1,7], toppingCosts = [3,4], target = 10 输出:10 解释:考虑下面的方案组合(所有下标均从 0 开始): - 选择 1 号基料:成本 7 - 选择 1 份 0 号配料:成本 1 x 3 = 3 - 选择 0 份 1 号配料:成本 0 x 4 = 0 总成本:7 + 3 + 0 = 10 。
示例 2:
输入:baseCosts = [2,3], toppingCosts = [4,5,100], target = 18 输出:17 解释:考虑下面的方案组合(所有下标均从 0 开始): - 选择 1 号基料:成本 3 - 选择 1 份 0 号配料:成本 1 x 4 = 4 - 选择 2 份 1 号配料:成本 2 x 5 = 10 - 选择 0 份 2 号配料:成本 0 x 100 = 0 总成本:3 + 4 + 10 + 0 = 17 。不存在总成本为 18 的甜点制作方案。
示例 3:
输入:baseCosts = [3,10], toppingCosts = [2,5], target = 9 输出:8 解释:可以制作总成本为 8 和 10 的甜点。返回 8 ,因为这是成本更低的方案。
示例 4:
输入:baseCosts = [10], toppingCosts = [1], target = 1 输出:10 解释:注意,你可以选择不添加任何配料,但你必须选择一种基料。
提示:
n == baseCosts.length
m == toppingCosts.length
1 <= n, m <= 10
1 <= baseCosts[i], toppingCosts[i] <= 104
1 <= target <= 104
原站题解
python3 解法, 执行用时: 220 ms, 内存消耗: 15.1 MB, 提交时间: 2022-12-04 10:09:12
class Solution: def closestCost(self, baseCosts: List[int], toppingCosts: List[int], target: int) -> int: x = min(baseCosts) if x > target: return x # 我们设 can[i] 表示对于甜品制作开销为 i 是否存在合法方案,如果存在则其等于 true,否则为 false,初始为 false。 can = [False] * (target + 1) ans = 2 * target - x for c in baseCosts: if c <= target: can[c] = True else: ans = min(ans, c) # 我们按「01 背包」的方法来依次枚举配料来进行放置,因为每种配料我们最多只能选两份, # 所以我们可以直接将每种配料变为两个,然后对于两个配料都进行放置即可。 for c in toppingCosts: for count in range(2): for i in range(target, 0, -1): if can[i] and i + c > target: ans = min(ans, i + c) if i - c > 0 and not can[i]: can[i] = can[i - c] for i in range(ans - target + 1): if can[target - i]: return target - i return ans
golang 解法, 执行用时: 4 ms, 内存消耗: 2.2 MB, 提交时间: 2022-12-04 10:02:34
func closestCost(baseCosts []int, toppingCosts []int, target int) int { x := baseCosts[0] for _, c := range baseCosts { x = min(x, c) } if x > target { return x } can := make([]bool, target+1) ans := 2*target - x for _, c := range baseCosts { if c <= target { can[c] = true } else { ans = min(ans, c) } } for _, c := range toppingCosts { for count := 0; count < 2; count++ { for i := target; i > 0; i-- { if can[i] && i+c > target { ans = min(ans, i+c) } if i-c > 0 { can[i] = can[i] || can[i-c] } } } } for i := 0; i <= ans-target; i++ { if can[target-i] { return target - i } } return ans } func min(a, b int) int { if a > b { return b } return a }
javascript 解法, 执行用时: 84 ms, 内存消耗: 44.3 MB, 提交时间: 2022-12-04 10:02:20
/** * @param {number[]} baseCosts * @param {number[]} toppingCosts * @param {number} target * @return {number} */ var closestCost = function(baseCosts, toppingCosts, target) { const x = _.min(baseCosts); if (x >= target) { return x; } const can = new Array(target + 1).fill(0); let res = 2 * target - x; for (const b of baseCosts) { if (b <= target) { can[b] = true; } else { res = Math.min(res, b); } } for (const t of toppingCosts) { for (let count = 0; count < 2; ++count) { for (let i = target; i > 0; --i) { if (can[i] && i + t > target) { res = Math.min(res, i + t); } if (i - t > 0) { can[i] = can[i] | can[i - t]; } } } } for (let i = 0; i <= res - target; ++i) { if (can[target - i]) { return target - i; } } return res; }
java 解法, 执行用时: 5 ms, 内存消耗: 39 MB, 提交时间: 2022-12-04 10:02:04
class Solution { public int closestCost(int[] baseCosts, int[] toppingCosts, int target) { int x = Arrays.stream(baseCosts).min().getAsInt(); if (x >= target) { return x; } boolean[] can = new boolean[target + 1]; int res = 2 * target - x; for (int b : baseCosts) { if (b <= target) { can[b] = true; } else { res = Math.min(res, b); } } for (int t : toppingCosts) { for (int count = 0; count < 2; ++count) { for (int i = target; i > 0; --i) { if (can[i] && i + t > target) { res = Math.min(res, i + t); } if (i - t > 0) { can[i] = can[i] | can[i - t]; } } } } for (int i = 0; i <= res - target; ++i) { if (can[target - i]) { return target - i; } } return res; } }
java 解法, 执行用时: 4 ms, 内存消耗: 38.9 MB, 提交时间: 2022-12-04 10:01:08
class Solution { int res; public int closestCost(int[] baseCosts, int[] toppingCosts, int target) { res = Arrays.stream(baseCosts).min().getAsInt(); for (int b : baseCosts) { dfs(toppingCosts, 0, b, target); } return res; } public void dfs(int[] toppingCosts, int p, int curCost, int target) { if (Math.abs(res - target) < curCost - target) { return; } else if (Math.abs(res - target) >= Math.abs(curCost - target)) { if (Math.abs(res - target) > Math.abs(curCost - target)) { res = curCost; } else { res = Math.min(res, curCost); } } if (p == toppingCosts.length) { return; } dfs(toppingCosts, p + 1, curCost + toppingCosts[p] * 2, target); dfs(toppingCosts, p + 1, curCost + toppingCosts[p], target); dfs(toppingCosts, p + 1, curCost, target); } }
golang 解法, 执行用时: 0 ms, 内存消耗: 1.8 MB, 提交时间: 2022-12-04 10:00:47
func closestCost(baseCosts []int, toppingCosts []int, target int) int { ans := baseCosts[0] for _, c := range baseCosts { ans = min(ans, c) } var dfs func(int, int) dfs = func(p, curCost int) { if abs(ans-target) < curCost-target { return } else if abs(ans-target) >= abs(curCost-target) { if abs(ans-target) > abs(curCost-target) { ans = curCost } else { ans = min(ans, curCost) } } if p == len(toppingCosts) { return } dfs(p+1, curCost+toppingCosts[p]*2) dfs(p+1, curCost+toppingCosts[p]) dfs(p+1, curCost) } for _, c := range baseCosts { dfs(0, c) } return ans } func abs(x int) int { if x < 0 { return -x } return x } func min(a, b int) int { if a > b { return b } return a }
javascript 解法, 执行用时: 56 ms, 内存消耗: 41 MB, 提交时间: 2022-12-04 10:00:32
/** * @param {number[]} baseCosts * @param {number[]} toppingCosts * @param {number} target * @return {number} */ var closestCost = function(baseCosts, toppingCosts, target) { let res = _.min(baseCosts); const dfs = (toppingCosts, p, curCost, target) => { if (Math.abs(res - target) < curCost - target) { return; } else if (Math.abs(res - target) >= Math.abs(curCost - target)) { if (Math.abs(res - target) > Math.abs(curCost - target)) { res = curCost; } else { res = Math.min(res, curCost); } } if (p === toppingCosts.length) { return; } dfs(toppingCosts, p + 1, curCost + toppingCosts[p] * 2, target); dfs(toppingCosts, p + 1, curCost + toppingCosts[p], target); dfs(toppingCosts, p + 1, curCost, target); }; for (const b of baseCosts) { dfs(toppingCosts, 0, b, target); } return res; }
python3 解法, 执行用时: 280 ms, 内存消耗: 15 MB, 提交时间: 2022-12-04 10:00:12
class Solution: def closestCost(self, baseCosts: List[int], toppingCosts: List[int], target: int) -> int: ans = min(baseCosts) def dfs(p: int, cur_cost: int) -> None: nonlocal ans if abs(ans - target) < cur_cost - target: return if abs(ans - target) >= abs(cur_cost - target): if abs(ans - target) > abs(cur_cost - target): ans = cur_cost else: ans = min(ans, cur_cost) if p == len(toppingCosts): return dfs(p + 1, cur_cost + toppingCosts[p] * 2) dfs(p + 1, cur_cost + toppingCosts[p]) dfs(p + 1, cur_cost) for c in baseCosts: dfs(0, c) return ans