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

难度中等55

你打算做甜点,现在需要购买配料。目前共有 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
解释:注意,你可以选择不添加任何配料,但你必须选择一种基料。

提示:

DFS

DFS得到配料所有可能的成本,然后对每一种基料找到最接近target的。

class Solution {int best = (int)1e9;int target;public int closestCost(int[] baseCosts, int[] toppingCosts, int target) {this.target = target;for(int i = 0; i < baseCosts.length; i++){dfs(toppingCosts, 0, baseCosts[i]);}return best;}//暴搜,数据量很小,枚举每个选择就可以public void dfs(int[] arr, int idx, int cost){int sign = Math.abs(best-target) - Math.abs(cost-target);// sign > 0 : 说明当前cost比best离target的差值小//(sign == 0 && cost < best) : 成本相同,且成本比best低if(sign > 0 || (sign == 0 && cost < best)){best = cost;}//剪支以下,如果当前的成本已经大于cost,没有必要再往后就行选择//或者已经遍历完,结束if(cost >= target || idx == arr.length){return;}//每个配料可以选0,1,2份for(int k = 0; k < 3; k++){dfs(arr, idx+1, cost + arr[idx]*k);}}
}

01背包

题解:https://leetcode.cn/problems/closest-dessert-cost/solution/di-gui-hui-su-huo-0-1bei-bao-wen-ti-by-w-3hhr/

动态规划,0-1背包问题来做。看成本选得到,选不到的问题。冰淇凌选且仅选一个,所以每个冰淇凌的成本都能选到。然后配料可以选0-2份,遍历配料,看在这基础上有哪些成本可以取到。然后看能取到的成本中,哪个最接近target。时间复杂度O(n+m⋅20000)。

public class leetcode5690 {// 动态规划,0-1背包问题public int closestCost(int[] baseCosts, int[] toppingCosts, int target) {int n = baseCosts.length;int m = toppingCosts.length;// target最多10000,冰淇凌和配料也最多一万,答案不会超过20000boolean[] dp = new boolean[20001];// 每个冰淇凌只能选一个for(int i = 0;i < n;i++){dp[baseCosts[i]] = true;}// 配料可以选0-2份,扩展一倍int[] topping = Arrays.copyOf(toppingCosts, m * 2);for(int i = m;i < 2 * m;i++){topping[i] = topping[i-m];}// 枚举物品for(int i = 0;i < 2 * m;i++){int cur = topping[i];// 如果前一个成本能选到,加了这个配料的价格后,也能选到for(int j = 20000;j > cur;j--){dp[j] = dp[j] || dp[j-cur];}}int ans = 0;int dif = 30000;// 看可以选到的成本,哪个最接近targetfor(int i = 1;i < 20001;i++){int cur = Math.abs(i-target);if(dp[i] && cur < dif){dif = cur;ans = i;}}return ans;}
}

三进制状态压缩

题解:https://leetcode.cn/problems/closest-dessert-cost/solution/javayong-shi-nei-cun-shuang-100san-jin-z-3jdx/

考虑到baseCosts、toppingCosts的长度最多都为10,每一种辅料都有加0、1、2份的选择,因此可以考虑三进制状态压缩求解。

类似二进制的状态压缩。

class Solution {public int closestCost(int[] baseCosts, int[] toppingCosts, int target) {Arrays.sort(baseCosts);Arrays.sort(toppingCosts);int nearestCost=0;//记录最接近的成本int minGap = Integer.MAX_VALUE;//记录目前最接近的成本和目标成本target的差for(int i=0;i<baseCosts.length;i++){//每一种基料for(int j=0;j<Math.pow(3,toppingCosts.length);j++){//三进制位串int cost = baseCosts[i];int curJ = j;//现在的位串int index = 0;while(curJ!=0){//取位串的每一位int curBit = curJ % 3;//位串的当前一位curJ /= 3;cost += toppingCosts[index]*curBit;index++;}if(Math.abs(cost-target)==0){//若现在的成本恰好是target,直接返回return target;}else if(Math.abs(cost-target)<minGap){//若目前的成本更接近target,更新nearestCost和minGap;minGap = Math.abs(cost-target);nearestCost = cost;}else if(Math.abs(cost-target)==minGap){//若目前的成本和已经找到的最接近成本与目标成本的差距相等,取成本较小者(题目要求)if(cost<nearestCost){nearestCost = cost;}}}}return nearestCost;}
}

补充

假如一个数的三进制为2 1 2 0 0,则

int sum = 0;
int idx = i;
int cur = 0;
while(idx!=0){sum+=toppingCosts[cur]*(idx%3);idx/=3;cur++;
}

则该代码块执行的功能就是 toppingCosts的 [0]·0 + [1]·[0] + [2]·2 + [3]·1 + [4]·2

枚举完辅料的所有可能后开始枚举主料,依次比较即可。

  • 时间复杂度为 O(n·3^m)。
  • 空间复杂度为 O(1)。

LC-1774. 最接近目标价格的甜点成本(DFS、01背包、三进制状态枚举)相关推荐

  1. LeetCode 1774. 最接近目标价格的甜点成本(DFS / 01背包)

    文章目录 1. 题目 2. 解题 1. 题目 你打算做甜点,现在需要购买配料.目前共有 n 种冰激凌基料和 m 种配料可供选购.而制作甜点需要遵循以下几条规则: 必须选择 一种 冰激凌基料. 可以添加 ...

  2. C语言在BST中找到最接近目标的值的算法(附完整源码)

    C语言在BST中找到最接近目标的值的算法 C语言在BST中找到最接近目标的值的算法完整源码(定义,实现,main函数测试) C语言在BST中找到最接近目标的值的算法完整源码(定义,实现,main函数测 ...

  3. (算法)求数组中数字组合(可多值组合)相加最接近目标数的组合(可能多个)

      今天没事,撸一道算法题   题目要求: 给出一个升序排序的可能重复值的数字数组和一个目标值其中目标值大于数组中最小数,求数组中数字组合(可多值组合)相加最接近目标数的组合(可能多个)不考虑空间复杂 ...

  4. 寻找数组中最接近目标的数字,Java实现

    给出一个排好序的整数数组.需要找到与给定数字最接近的值.数组可能包含重复的值 和负数. 例: Input : arr[] = {1, 2, 4, 5, 6, 6, 8, 9} Target numbe ...

  5. 瑞信研报:甲骨文跑赢大盘 目标价格38美元

    导读:甲骨文(ORCL)将于3月24日盘后发布第三财季财报.瑞信在3月8日发布的甲骨文研报对该股的评级为"跑赢大盘",目标价格为38美元. 以下是该研报摘译: 第三财季前瞻 虽然从 ...

  6. 目标和(01背包应用)

    给你一个整数数组 nums 和一个整数 target . 向数组中的每个整数前添加 '+' 或 '-' ,然后串联起所有整数,可以构造一个 表达式 : 例如,nums = [2, 1] ,可以在 2 ...

  7. 项目管理的三大目标即时间、成本和质量

    项目管理的三大目标即时间.成本和质量,实际是告诉项目经理应重点关注什么因素,项目控制应该做什么工作.三大目标虽然简单,但如果 能将其真正贯彻到自己的行动中,那么对项目计划制定.过程控制等工作,均能起到 ...

  8. 三进制计算机_三进制半导体诞生,逻辑比二进制更接近人类思维?

    7月17日,据韩媒报道,韩国一个科研团队已成功在大尺寸晶圆上成功实现了一种更节能的三元金属氧化物半导体. 韩国蔚山科学技术大学(UNIST)电子和计算机工程系教授Kim Kyung Rok及其团队,在 ...

  9. 数组中的三数之和最接近目标数

    题目: 给你一个长度为 n 的整数数组 nums 和 一个目标值 target.请你从 nums 中选出三个整数,使它们的和与 target 最接近. 返回这三个数的和. 假定每组输入只存在恰好一个解 ...

  10. 洛谷 1774 最接近神的人

    [题解] 其实就是求逆序对.直接上树状数组就好了. 1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring ...

最新文章

  1. 获取某个元素相对于视窗的位置-getBoundingClientRect
  2. 前众信旅游B端产品经理吴彪:如何搭建B端电商产品及用户体系
  3. Android 开发学习资源
  4. c语言的使用比例远远高于python语言对吗_Python和C语言的语法有什么不同?
  5. MVC三层架构(详解)
  6. Visual Paradigm(一)简介和软件初步
  7. ArcGIS:ArcToolBox工具使用——提取DEM/DSM中的高程点
  8. 字节跳动面试:java后端面试宝典
  9. Windows Phone中Map控件由浅及深
  10. C++ plus Primer 第六版中文版 带书签的 PDF
  11. android手机 ipad 同屏,iphone和ipad
  12. linux steam大屏幕模式,Steam 大屏幕模式 - Steam Support
  13. 每日小结(就不平衡问题探讨)
  14. 读《如何阅读一本书》乱摘
  15. Spring Bean前置后置处理器的使用
  16. 【高等数学笔记】二元函数连续、可微、偏导数存在、偏导数连续、任意方向导数存在的关系
  17. 华为meta30浏览器不兼容flex布局解决方案-加前缀
  18. 清华刘知远团队巨作!Pre-trained Prompt Tuning框架,让超大模型调参变简单
  19. 海贼王---追了好久的动漫了闲来无事发几张图嘿嘿
  20. 【区块链 | Solidity】以太坊Solidity如何实现海量空投代币?

热门文章

  1. 工程师职称评审的好处
  2. 三步上线自己的在线监考系统
  3. SQL Server时间相关查询
  4. android 日志自动过滤器
  5. 小舍图片Api接口【老司机都懂】
  6. IO[File_API学习]
  7. FreeSWITCH 1.10.10 简单图形化界面1 - docker/脚本/ISO镜像安装
  8. 物联网的体系架构阐述
  9. 【源码项目】C语言编程之火车票管理系统!(最强代码)
  10. 运营商服务器停电,断网、停电、死机怎么办?最详细智慧票务系统应急解决方案...