638. 大礼包

在LeetCode商店中, 有许多在售的物品。

然而,也有一些大礼包,每个大礼包以优惠的价格捆绑销售一组物品。

现给定每个物品的价格,每个大礼包包含物品的清单,以及待购物品清单。请输出确切完成待购清单的最低花费。

每个大礼包的由一个数组中的一组数据描述,最后一个数字代表大礼包的价格,其他数字分别表示内含的其他种类物品的数量。

任意大礼包可无限次购买。

示例 1:

输入: [2,5], [[3,0,5],[1,2,10]], [3,2]
输出: 14
解释:
有A和B两种物品,价格分别为¥2和¥5。
大礼包1,你可以以¥5的价格购买3A和0B。
大礼包2, 你可以以¥10的价格购买1A和2B。
你需要购买3个A和2个B, 所以你付了¥10购买了1A和2B(大礼包2),以及¥4购买2A。
示例 2: 输入: [2,3,4], [[1,1,0,4],[2,2,1,9]], [1,2,1]
输出: 11
解释:
A,B,C的价格分别为¥2,¥3,¥4.
你可以用¥4购买1A和1B,也可以用¥9购买2A,2B和1C。
你需要买1A,2B和1C,所以你付了¥4买了1A和1B(大礼包1),以及¥3购买1B, ¥4购买1C。
你不可以购买超出待购清单的物品,尽管购买大礼包2更加便宜。
说明: 最多6种物品, 100种大礼包。
每种物品,你最多只需要购买6个。
你不可以购买超出待购清单的物品,即使更便宜。

PS:

经典DFS,除了操作复杂以外,

简述题目:

三个list,第一个list是每个物品单价,

第二个list是大礼包详情,每个大礼包中最后一个为大礼包的价格,前面的是礼包中各个物品的数量,

第三个list是你需要购买的各个物品的数量

class Solution {
//全局保存
private List<Integer> global_needs, global_price;
private List<List<Integer>> global_special;
private int sum = 0, res = Integer.MAX_VALUE; public int shoppingOffers(List<Integer> price, List<List<Integer>> special, List<Integer> needs) {
global_needs = needs;
global_special = special;
global_price = price;
find(0);
return res;
} private void find(int begin) {
int temp_sum = sum;
// 最坏的情况单价买
for (int i = 0; i < global_needs.size(); ++i)
sum += global_needs.get(i) * global_price.get(i);
res = Math.min(res, sum); sum = temp_sum;
for (int i = begin; i < global_special.size(); ++i) {
List<Integer> cur_special = global_special.get(i);
int special_num = cal_special_num(cur_special);
for (int j = 1; j <= special_num; ++j) { List<Integer> temp_needs = new ArrayList<>(global_needs); for (int k = 0; k < global_needs.size(); ++k)
global_needs.set(k, global_needs.get(k) - cur_special.get(k) * j);
sum += cur_special.get(global_needs.size()) * j; find(i + 1); global_needs = temp_needs;
sum = temp_sum;
} }
} //最多需要多少
private int cal_special_num(List<Integer> item) {
int max = Integer.MAX_VALUE;
for (int i = 0; i < global_needs.size(); ++i) {
if (global_needs.get(i) < item.get(i))
return 0;
if (item.get(i) != 0)
max = Math.min(global_needs.get(i) / item.get(i), max);
}
return max;
}
}

Java实现 LeetCode 638 大礼包(阅读理解题,DFS)的更多相关文章

  1. UVALive 7270 Osu! Master (阅读理解题)

    题目:传送门. 题意:阅读理解题,是一个osu的游戏,问得分.把题目翻译过来就是如果出现S或者BC后面跟的是1,ans就加1. #include <iostream> #include & ...

  2. Java实现 LeetCode 1111 有效括号的嵌套深度(阅读理解题,位运算)

    1111. 有效括号的嵌套深度 有效括号字符串 定义:对于每个左括号,都能找到与之对应的右括号,反之亦然.详情参见题末「有效括号字符串」部分. 嵌套深度 depth 定义:即有效括号字符串嵌套的层数, ...

  3. leetcode: 638.大礼包

    题目描述: https://leetcode-cn.com/problems/shopping-offers/ 解题思路: 这类求最大最小的问题首先想到的就是用DP求解. 这题还用到了递归,首先计算单 ...

  4. 4609: [Wf2016]Branch Assignment 最短路 DP (阅读理解题)

    Bzoj的翻译出锅了所以来官方题面:这个题应该是单向边而BZOJ说的是双向边,什么你WA了?谁叫你懒得看英文...... 显然我们能正向反向两遍SPFA处理出每个点到总部的距离和总部到每个点的距离.如 ...

  5. Java实现 LeetCode 834 树中距离之和(DFS+分析)

    834. 树中距离之和 给定一个无向.连通的树.树中有 N 个标记为 0-N-1 的节点以及 N-1 条边 . 第 i 条边连接节点 edges[i][0] 和 edges[i][1] . 返回一个表 ...

  6. Java实现 LeetCode 784 字母大小写全排列(DFS)

    784. 字母大小写全排列 给定一个字符串S,通过将字符串S中的每个字母转变大小写,我们可以获得一个新的字符串.返回所有可能得到的字符串集合. 示例: 输入: S = "a1b2" ...

  7. Java实现 LeetCode 756 金字塔转换矩阵(DFS)

    756. 金字塔转换矩阵 现在,我们用一些方块来堆砌一个金字塔. 每个方块用仅包含一个字母的字符串表示. 使用三元组表示金字塔的堆砌规则如下: 对于三元组(A, B, C) ,"C" ...

  8. Java实现 LeetCode 691 贴纸拼词(DFS+map记录)

    691. 贴纸拼词 我们给出了 N 种不同类型的贴纸.每个贴纸上都有一个小写的英文单词. 你希望从自己的贴纸集合中裁剪单个字母并重新排列它们,从而拼写出给定的目标字符串 target. 如果你愿意的话 ...

  9. Java实现 LeetCode 664 奇怪的打印机(DFS)

    664. 奇怪的打印机 有台奇怪的打印机有以下两个特殊要求: 打印机每次只能打印同一个字符序列. 每次可以在任意起始和结束位置打印新字符,并且会覆盖掉原来已有的字符. 给定一个只包含小写英文字母的字符 ...

随机推荐

  1. Android Bluetooth How To--Based on Android L Bluedroid

    Android Bluetooth How To(Based on Android L Bluedroid) 持续更新中… 1.How to enable btsnoop log? a) UI Set ...

  2. uCOS2014.1.8

    目前uCOS中已经接触到的全局变量: OSTCBCur OSIntNesting OSPrioHighRdy    最高优先级任务 任哲编著<嵌入式实时操作系统uC/OS-II原理及应用> ...

  3. DP之石子堆合并问题

    相邻 环形 总结 (1)相邻:在一个圆形操场的四周摆放着n堆石子(n<= 100),现要将石子有次序地合并成一堆.规定每次只能选取相邻的两堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得 ...

  4. [hdu4123]dfs区间化+RMQ

    题意:给一个树编号0~n-1,一个数组a[i]为节点i在树上走的最大距离(不重复点),然后求最大的区间,使得区间最大差异小于某个值.dfs求出每个数组,同时区间化.枚举区间左边界,右边界同样递增,类似 ...

  5. shell 光标处理快捷键

    Ctrl+左右键 单词之间跳转Ctrl+a跳到本行的行首, Ctrl+e则跳到页尾. Ctrl+u删除当前光标前面的文字 ctrl+k-删除当前光标后面的文字 Ctrl+w和Alt+d-对于当前的单词 ...

  6. X-CTF(REVERSE高级) 666

    主函数输入的字符会和key比较长度和enflag比较内容,所以这道题的flag和输入有关 key长度为0x12,enflag的值为:izwhroz""w"v.K" ...

  7. 前端面试题-TCP和UDP的区别

    TCP和UDP的区别 (1)TCP是面向连接的,udp是无连接的即发送数据前不需要先建立链接. (2)TCP提供可靠的服务.也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UD ...

  8. Python中的时间与日期

    本文简要介绍datetime,time模块的简要用法. datetime模块 datetime模块主要有四个主要的对象. date 处理年.月.日 time处理时.分.秒.微秒 datetime处理日 ...

  9. 最短路径——dijkstra算法代码(c语言)

    最短路径问题 看了王道的视频,感觉云里雾里的,所以写这个博客来加深理解.(希望能在12点以前写完) 一.总体思想 dijkstra算法的主要思想就是基于贪心,找出从v开始的顶点到各个点的最短路径,做法 ...

  10. ⚠ | 不要再使用 markdown 主题了!

    前置 我在很久之前就发现了使用第三方 markdown 主题将产生一个的问题,今日在社区发现依然有人写文章来推荐这种做法.接下来我告诉你为什么最好不要这样做以及分享一些 markdown 技巧.若有不 ...