In the 638. Shopping Offers
problem, you are given several items that you want to buy, and you have multiple offers that you can use to purchase these items at a discount. Each offer specifies how many of each type of item you receive and the total price of the offer. You need to determine the minimum cost to buy a specified quantity of each item.
Here is the formal problem statement:
You have n
items that you want to buy, and you are given an integer array price
where price[i]
is the price of the i-th
item.
special
where each offer is an array with n+1
elements. The first n
elements of the array represent the quantity of each item included in the offer, and the last element represents the price you pay for this offer.needs
where needs[i]
is the number of units of the i-th
item that you need to buy.You need to return the minimum cost to satisfy all of the given needs
.
#include <vector>
#include <unordered_map>
using namespace std;
class Solution {
public:
int shoppingOffers(vector<int>& price, vector<vector<int>>& special, vector<int>& needs) {
// Memoization cache
unordered_map<string, int> memo;
return dfs(price, special, needs, memo);
}
private:
int dfs(vector<int>& price, vector<vector<int>>& special, vector<int>& needs, unordered_map<string, int>& memo) {
string key = getKey(needs);
if (memo.find(key) != memo.end()) {
return memo[key];
}
// Calculate the original price without any offers
int minCost = 0;
for (int i = 0; i < needs.size(); ++i) {
minCost += needs[i] * price[i];
}
// Try to apply each special offer
for (auto &offer : special) {
vector<int> remainingNeeds = needs;
bool valid = true;
for (int i = 0; i < needs.size(); ++i) {
remainingNeeds[i] -= offer[i];
if (remainingNeeds[i] < 0) {
valid = false;
break;
}
}
if (valid) {
minCost = min(minCost, offer.back() + dfs(price, special, remainingNeeds, memo));
}
}
memo[key] = minCost;
return minCost;
}
string getKey(vector<int>& needs) {
string key;
for (int need : needs) {
key += to_string(need) + ",";
}
return key;
}
};
needs
, we try to apply each offer if valid and then recursively solve the subproblem with the remaining needs.Got blindsided by a question you didn’t expect?
Spend too much time studying?
Or simply don’t have the time to go over all 3000 questions?