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

news2024/9/22 19:42:19

来源:力扣(LeetCode)

描述:

你打算做甜点,现在需要购买配料。目前共有 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
- 选择 10 号配料:成本 1 x 3 = 3
- 选择 01 号配料:成本 0 x 4 = 0
总成本:7 + 3 + 0 = 10

示例 2:

输入:baseCosts = [2,3], toppingCosts = [4,5,100], target = 18
输出:17
解释:考虑下面的方案组合(所有下标均从 0 开始):
- 选择 1 号基料:成本 3
- 选择 10 号配料:成本 1 x 4 = 4
- 选择 21 号配料:成本 2 x 5 = 10
- 选择 02 号配料:成本 0 x 100 = 0
总成本:3 + 4 + 10 + 0 = 17 。不存在总成本为 18 的甜点制作方案。

示例 3:

输入:baseCosts = [3,10], toppingCosts = [2,5], target = 9
输出:8
解释:可以制作总成本为 810 的甜点。返回 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

方法一:回溯

思路与算法

  首先题目给出长度分别为 n 的冰淇淋基料数组 baseCosts 和长度为 m 的配料数组 toppingCosts ,其中 baseCosts[i] 表示第 i 种冰淇淋基料的价格,toppingCosts[j] 表示一份第 j 种冰淇淋配料的价格,以及一个整数 target 表示我们需要制作甜点的目标价格。现在在制作甜品上我们需要遵守以下三条规则:

  • 必须选择一种冰淇淋基料;
  • 可以添加一种或多种配料,也可以不添加任何配料;
  • 每种配料最多两份

  我们希望做的甜点总成本尽可能接近目标价格 target ,那么我们现在按照规则对于每一种冰淇淋基料用回溯的方式来针对它进行甜品制作。又因为每一种配料都是正整数,所以在回溯的过程中总开销只能只增不减,当回溯过程中当前开销大于目标价格 target 后,继续往下搜索只能使开销与 target 的差值更大,所以如果此时差值已经大于等于我们已有最优方案的差值,我们可以停止继续往下搜索,及时回溯。

代码:

class Solution {
public:
    void dfs(const vector<int>& toppingCosts, int p, int curCost, int& res, const int& target) {
        if (abs(res - target) < curCost - target) {
            return;
        } else if (abs(res - target) >= abs(curCost - target)) {
            if (abs(res - target) > abs(curCost - target)) {
                res = curCost;
            } else {
                res = min(res, curCost);
            }
        }
        if (p == toppingCosts.size()) {
            return;
        }
        dfs(toppingCosts, p + 1, curCost + toppingCosts[p] * 2, res, target);
        dfs(toppingCosts, p + 1, curCost + toppingCosts[p], res, target);
        dfs(toppingCosts, p + 1, curCost, res, target);
    }

    int closestCost(vector<int>& baseCosts, vector<int>& toppingCosts, int target) {
        int res = *min_element(baseCosts.begin(), baseCosts.end());
        for (auto& b : baseCosts) {
            dfs(toppingCosts, 0, b, res, target);
        }
        return res;
    }
};

1

复杂度分析
时间复杂度:O(n×3m),其中 nnn,mmm 分别为数组 baseCosts,toppingCosts 的长度。
空间复杂度:O(m),主要为回溯递归的空间开销。

方法二:动态规划

思路与算法

  我们可以将问题转化为对于某一个开销是否存在甜品制作方案问题,然后我们选择与目标价格最接近的合法甜品制作方案即可,那么问题就转化为了「01 背包」问题(关于「01 背包」的概念可见 百度百科)。这样我们就可以把问题求解从指数级别降到多项式级别了。对于「01 背包」的求解我们可以用「动态规划」来解决。

  设最小的基料开销为 x。若 x ≥ target ,则无论我们是否添加配料都不会使甜品制作的开销与目标价格 target 的距离缩小,所以此时直接返回此最小的基料开销即可。当最小的基料开销小于 target 时,我们可以对超过 target 的制作开销方案只保存其最小的一份即可,并可以初始化为 2 × target − x ,因为大于该开销的方案与目标价格 target 的距离一定大于仅选最小基料的情况,所以一定不会是最优解。将背包的容量 MAXC 设置为 target 。然后我们按「01 背包」的方法来依次枚举配料来进行放置。

  我们设 can[i] 表示对于甜品制作开销为 i 是否存在合法方案,如果存在则其等于 true,否则为 false,初始为 false。因为单独选择一种基料的情况是合法的,所以我们对 can 进行初始化:

can[x]= true, ∀x ∈ baseCosts & x < MAXC

  然后我们按「01 背包」的方法来依次枚举配料来进行放置,因为每种配料我们最多只能选两份,所以我们可以直接将每种配料变为两个,然后对于两个配料都进行放置即可。因为任意一个合法方案加上一份配料一定也为合法制作方案。所以当要放置的配料开销为 y 时,对于开销为 c, c > y 的转移方程为:

can[c] = can[c−y] ∣ can[c],c > y

  因为每一个状态的求解只和前面的状态有关,所以我们可以从后往前来更新每一个状态。然后当配料全部放置后,我们可以从目标价格 target 往左搜索找到最接近 target 的合法方案并与大于 target 的方案做比较返回与 target 更接近的方案即可。

代码:

class Solution {
public:
    int closestCost(vector<int>& baseCosts, vector<int>& toppingCosts, int target) {
        int x = *min_element(baseCosts.begin(), baseCosts.end());
        if (x >= target) {
            return x;
        }
        vector<bool> can(target + 1, false);
        int res = 2 * target - x;
        for (auto& b : baseCosts) {
            if (b <= target) {
                can[b] = true;
            } else {
                res = min(res, b);
            }
        }
        for (auto& t : toppingCosts) {
            for (int count = 0; count < 2; ++count) {
                for (int i = target; i; --i) {
                    if (can[i] && i + t > target) {
                        res = 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;
    }
};

2

复杂度分析
时间复杂度:O(target × m) ,其中 m 为数组 toppingCosts 的长度,target 为目标值。动态规划的时间复杂度是 O(MAXC × m) ,由于 MAXC = target ,因此时间复杂度是 O(target × m) 。
空间复杂度:O(target) ,其中 target 为目标值。需要创建长度为 target + 1 的数组 can。
author:力扣官方题解

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/59827.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[附源码]计算机毕业设计ssm校园一卡通服务平台

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

Apache+PHP8+MYSQL的配置(目前最新版本)

已有很多年没有WEB开发了&#xff0c;本机都没了测试的服务环境&#xff0c;前几天GO语言的一个测试用例需要用到WEB&#xff0c;于是快速搭建一个Apche环境&#xff0c;也顺便将PHP和MYSQL的环境也配置好&#xff0c;贴出来方便自己和他人&#xff0c;临时需要的时候就更快了&…

机器人控制算法八之路径规划算法:RRT、RRT-Connect、Dynamic-Domain RRTs*

机器人控制算法八之路径规划算法&#xff1a;RRT、RRT-Connect、Dynamic-Domain RRTs* 本文主要介绍基于RRT快速搜索随机树的路径规划算法及其改进&#xff0c;主要参考以下论文&#xff1a; 1.1998 Rapidly-exploring random trees: A new tool for path planning2.IEEE2000 R…

[附源码]计算机毕业设计基于springboot的家政服务平台

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

java毕业设计项目_第167期ssm多用户博客个人网站_计算机毕业设计

java毕业设计项目_第167期ssm多用户博客个人网站_计算机毕业设计 【源码请到资源专栏下载】 今天分享的项目是《ssm多用户博客个人网站》 该项目分为2个角色&#xff0c;管理员和用户。 用户可以浏览前台,包含功能有&#xff1a; 首页、博文类型、学生博客、论坛信息 、新闻资讯…

[附源码]Python计算机毕业设计Django框架的食品安全监督平台的设计与实现

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

Jsp+MySQL学生学籍信息管理系统 Java毕业设计

中学生学籍信息管理系统主要有三个访问权限。首先是管理员,管理员是整个系统的所有功能的管理者,有对学科、班级、教师、学生学籍信息、课表、学生身体素质以及教务公告的管理权限,可以对以上所有信息进行增删改查&#xff1a;教师角色则有查看教务公告和修改所教授科目对应班级…

大数据:Sqoop 简介与安装

一、Sqoop 简介 Sqoop 是一个常用的数据迁移工具&#xff0c;主要用于在不同存储系统之间实现数据的导入与导出&#xff1a; 导入数据&#xff1a;从 MySQL&#xff0c;Oracle 等关系型数据库中导入数据到 HDFS、Hive、HBase 等分布式文件存储系统中&#xff1b; 导出数据&am…

C++ Primer Plus第五版笔记(p101-150)

1 数组和vector类似&#xff0c;数组的大小确定不变&#xff0c;不能随意向数组中增加元素。 2 数组维度必须是一个常量表达式 3 不允许用auto关键字由初始值列表推断类型&#xff0c;另外和vector一样&#xff0c;数组的元素应该为对象&#xff0c;因此不存在引用的数组 4 字符…

7. TTL 延迟队列

二八佳人体似酥&#xff0c;腰间仗剑斩愚夫。虽然不见人头落&#xff0c;暗里教君骨髓枯。 创建两个队列 QA和 QB&#xff0c;两者队列 TTL 分别设置为 10S 和 40S&#xff0c;然后在创建一个交换机 X和死信交 换机 Y&#xff0c;它们的类型都是 direct&#xff0c;创建一个死信…

SpringBoot_项目打包部署

SpringBoot项目可以是jar类型的maven项目&#xff0c;也可以是一个war类型的maven项目&#xff0c;取决于我们要不要整合jsp使用。但是不管是哪种项目类型&#xff0c;已经不是我们传统意义上的项目结构了 在本地使用SpringBoot的启动器即可访问我们开发的项目。如果我们将项目…

尝试 vue 实现 SEO

背景: 官网使用 VUE 写的, 且 使用 <component /> 动态创建组件, 通过 手动配置的组件, 动态生成页面内容 然后收到通知, 需要实现 SEO , 于是就开始了 VUE SEO 的拉锯战..... 第一种尝试 VUEphantomjs 首先说下原理 phantomjs 是可以部署在服务端的 无头浏览器,…

最强大脑记忆曲线(12)-- 录入数据修改

录入数据修改一、设计思路二、解决过程2.1 设计修改窗口2.2 转成py文件2.3 写业务逻辑1、先显示一下基础页面2、配合适配器&#xff0c;自动调整窗口大小3、在数据录入窗口或背记窗口双击某条记录3.1 增加信号3.2 在槽函数中打开修改页面**3.3 两个页面之间传递信号**3.4 在子窗…

24点问题(带输出构造方式)

问题描述&#xff1a; 在屏幕上输入1〜10范围内的4个整数&#xff08;可以有重复&#xff09;&#xff0c;对它们进行加、减、乘、除四则运算后&#xff08;可以任意的加括号限定计算的优先级&#xff09;&#xff0c;寻找计算结果等于24的表达式。 例如输入4个整数4、5、6、7…

1. RabbitMq 的基本概念

参考使用: 尚硅谷 消息中间件 RabbitMQ 课件 MQ 的概念 什么是 MQ MQ(message queue)&#xff0c;从字面意思上看&#xff0c;本质是个队列&#xff0c;FIFO 先入先出&#xff0c;只不过队列中存放的内容是 message 而已&#xff0c;还是一种跨进程的通信机制&#xff0c;用…

[附源码]计算机毕业设计毕业生就业管理系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

Minecraft 1.19.2 Forge模组开发 05.矿石生成

我们本次尝试在主世界生成模组中自定义的矿石 1.由于1.19的版本出现了深板岩层的矿石&#xff0c;我们要在BlockInit类中声明一个矿石的两种岩层形态&#xff1a; BlockInit.java package com.joy187.re8joymod.init;import com.joy187.re8joymod.Main; import net.minecraf…

微服务框架 SpringCloud微服务架构 10 使用Docker 10.8 数据卷挂载案例1

微服务框架 【SpringCloudRabbitMQDockerRedis搜索分布式&#xff0c;系统详解springcloud微服务技术栈课程|黑马程序员Java微服务】 SpringCloud微服务架构 文章目录微服务框架SpringCloud微服务架构10 使用Docker10.8 数据卷挂载案例110.8.1 挂载数据卷10.8.2 案例10.8.3 总…

Pr:导出设置之高级设置及 VR 视频

视频 VIDEO设置因所选导出格式而异。每种格式都有独特的要求&#xff0c;这些要求决定了哪些设置可用。以导出文件格式为 H.264 为例&#xff0c;下面给出有关高级设置 Advanced Settings以及 VR 视频 VR Video的选项及说明。高级设置 Advanced Settings关键帧距离Key Frame Di…

期末复习-软件体系结构

软件体系结构一、软件重用与构件技术软件重用的定义重用驱动的软件的开发过程构件的三种描述模型三种构件分类方法的组织方式&#xff0c;检索方式&#xff0c;刻面分类法二、软件体系结构概述软件体系结构 构件 连接件 约束软件体系结构的四个发展阶段三、软件体系结构风格…