forked from ely-mitu/leetcode
-
Notifications
You must be signed in to change notification settings - Fork 0
/
ClosestDessertCost.cpp
107 lines (98 loc) · 3.69 KB
/
ClosestDessertCost.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
// Source : https://leetcode.com/problems/closest-dessert-cost/
// Author : Hao Chen
// Date : 2021-03-14
/*****************************************************************************************************
*
* You would like to make dessert and are preparing to buy the ingredients. You have n ice cream base
* flavors and m types of toppings to choose from. You must follow these rules when making your
* dessert:
*
* There must be exactly one ice cream base.
* You can add one or more types of topping or have no toppings at all.
* There are at most two of each type of topping.
*
* You are given three inputs:
*
* baseCosts, an integer array of length n, where each baseCosts[i] represents the price of
* the ith ice cream base flavor.
* toppingCosts, an integer array of length m, where each toppingCosts[i] is the price of one
* of the ith topping.
* target, an integer representing your target price for dessert.
*
* You want to make a dessert with a total cost as close to target as possible.
*
* Return the closest possible cost of the dessert to target. If there are multiple, return the lower
* one.
*
* Example 1:
*
* Input: baseCosts = [1,7], toppingCosts = [3,4], target = 10
* Output: 10
* Explanation: Consider the following combination (all 0-indexed):
* - Choose base 1: cost 7
* - Take 1 of topping 0: cost 1 x 3 = 3
* - Take 0 of topping 1: cost 0 x 4 = 0
* Total: 7 + 3 + 0 = 10.
*
* Example 2:
*
* Input: baseCosts = [2,3], toppingCosts = [4,5,100], target = 18
* Output: 17
* Explanation: Consider the following combination (all 0-indexed):
* - Choose base 1: cost 3
* - Take 1 of topping 0: cost 1 x 4 = 4
* - Take 2 of topping 1: cost 2 x 5 = 10
* - Take 0 of topping 2: cost 0 x 100 = 0
* Total: 3 + 4 + 10 + 0 = 17. You cannot make a dessert with a total cost of 18.
*
* Example 3:
*
* Input: baseCosts = [3,10], toppingCosts = [2,5], target = 9
* Output: 8
* Explanation: It is possible to make desserts with cost 8 and 10. Return 8 as it is the lower cost.
*
* Example 4:
*
* Input: baseCosts = [10], toppingCosts = [1], target = 1
* Output: 10
* Explanation: Notice that you don't have to have any toppings, but you must have exactly one base.
*
* Constraints:
*
* n == baseCosts.length
* m == toppingCosts.length
* 1 <= n, m <= 10
* 1 <= baseCosts[i], toppingCosts[i] <= 104
* 1 <= target <= 104
******************************************************************************************************/
class Solution {
private:
int abs_min (int x, int y, int z) {
return abs_min(x, abs_min(y, z));
}
// compare the absolute value and return the min one
// if their absolute value are equal, return the positive one.
int abs_min(int x, int y) {
int ax = abs(x);
int ay = abs(y);
if (ax == ay) return max(x, y);
return ax < ay ? x : y;
}
public:
int closestCost(vector<int>& baseCosts, vector<int>& toppingCosts, int target) {
int min_gap = INT_MAX;
for (auto& base : baseCosts) {
int gap = closetToppingCost(toppingCosts, target - base, 0);
min_gap = abs_min(min_gap, gap);
}
return target - min_gap;
}
int closetToppingCost(vector<int>& costs, int target, int idx ){
if (idx >= costs.size()) return target;
// three options: not slect, select once & select twice
int select_none = closetToppingCost(costs, target, idx+1);
int select_once = closetToppingCost(costs, target - costs[idx], idx+1);
int select_twice = closetToppingCost(costs, target - 2*costs[idx], idx+1);
return abs_min(select_none, select_once, select_twice);
}
};