列表

详情


1774. 最接近目标价格的甜点成本

你打算做甜点,现在需要购买配料。目前共有 n 种冰激凌基料和 m 种配料可供选购。而制作甜点需要遵循以下几条规则:

给你以下三个输入:

你希望自己做的甜点总成本尽可能接近目标价格 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
解释:注意,你可以选择不添加任何配料,但你必须选择一种基料。

 

提示:

原站题解

去查看

上次编辑到这里,代码来自缓存 点击恢复默认模板
class Solution { public: int closestCost(vector<int>& baseCosts, vector<int>& toppingCosts, int target) { } };

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

上一题