From 262380fadc7206ff83835aae0f23d7a1aa5b2826 Mon Sep 17 00:00:00 2001 From: Noob-coder-007 <117072754+Noob-coder-007@users.noreply.github.com> Date: Sat, 4 Oct 2025 12:06:55 +0530 Subject: [PATCH 1/2] Added 638. Shopping Offers --- 638. Shopping Offers | 98 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 638. Shopping Offers diff --git a/638. Shopping Offers b/638. Shopping Offers new file mode 100644 index 0000000..1610892 --- /dev/null +++ b/638. Shopping Offers @@ -0,0 +1,98 @@ +/* + * Shopping Offers (DFS + Memoization) + * + * Description: + * In LeetCode Store, there are n items to buy. Each has a normal price. + * Some special bundle offers let you buy multiple items together at a discount. + * You want to get all items in your "needs" list at the lowest total cost. + * + * Approach: + * - Use recursion (DFS) to try all ways of buying: + * 1. Buy items one-by-one at regular prices. + * 2. Try each special offer (if it doesn't exceed the needs). + * - Memoize the result for each unique "needs" state to avoid recomputation. + * + * Steps: + * 1. Define a helper function dfs(currentNeeds) → minimum cost for these needs. + * 2. Base cost = sum(need[i] * price[i]). + * 3. For each special offer: + * - Check if we can apply it (doesn't exceed needs). + * - If yes, subtract items and call dfs() recursively. + * 4. Memoize and return the minimum cost found. + * + * Time Complexity: O(n * product(needs[i])) (worst case) + * Space Complexity: O(product(needs[i])) (for memoization) + */ + +#include +using namespace std; + +class Solution { +public: + unordered_map memo; // memoization cache + + // Convert current needs to a string key for memo + string encode(vector& needs) { + string key; + for (int num : needs) key += to_string(num) + ","; + return key; + } + + // Recursive function to find the minimum cost + int dfs(vector& price, vector>& special, vector needs) { + string key = encode(needs); + if (memo.count(key)) return memo[key]; + + int n = price.size(); + int cost = 0; + + // Base case: buy all items individually + for (int i = 0; i < n; i++) { + cost += needs[i] * price[i]; + } + + // Try applying each special offer + for (auto& offer : special) { + vector newNeeds = needs; + bool valid = true; + + for (int i = 0; i < n; i++) { + newNeeds[i] -= offer[i]; + if (newNeeds[i] < 0) { // can't buy more than needed + valid = false; + break; + } + } + + if (valid) { + cost = min(cost, offer[n] + dfs(price, special, newNeeds)); + } + } + + memo[key] = cost; + return cost; + } + + int shoppingOffers(vector& price, vector>& special, vector& needs) { + memo.clear(); + return dfs(price, special, needs); + } +}; + +int main() { + Solution sol; + + // Test Case 1 + vector price1 = {2, 5}; + vector> special1 = {{3, 0, 5}, {1, 2, 10}}; + vector needs1 = {3, 2}; + cout << "Test Case 1: " << sol.shoppingOffers(price1, special1, needs1) << endl; // 14 + + // Test Case 2 + vector price2 = {2, 3, 4}; + vector> special2 = {{1, 1, 0, 4}, {2, 2, 1, 9}}; + vector needs2 = {1, 2, 1}; + cout << "Test Case 2: " << sol.shoppingOffers(price2, special2, needs2) << endl; // 11 + + return 0; +} From c549527948b1cb4f268d29fe62c4bf1477c811e1 Mon Sep 17 00:00:00 2001 From: SjxSubham Date: Sat, 4 Oct 2025 20:08:21 +0530 Subject: [PATCH 2/2] Add new file for Shopping Offers solution --- 638. Shopping Offers => 638. Shopping Offers.cpp | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename 638. Shopping Offers => 638. Shopping Offers.cpp (100%) diff --git a/638. Shopping Offers b/638. Shopping Offers.cpp similarity index 100% rename from 638. Shopping Offers rename to 638. Shopping Offers.cpp