-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSolution638.cs
66 lines (57 loc) · 2.12 KB
/
Solution638.cs
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
using LeetCode.DataStructures;
namespace LeetCode.Solutions;
public class Solution638
{
/// <summary>
/// 638. Shopping Offers - Medium
/// <a href="https://leetcode.com/problems/shopping-offers">See the problem</a>
/// </summary>
public int ShoppingOffers(IList<int> price, IList<IList<int>> special, IList<int> needs)
{
// Dictionary for memoization
var memo = new Dictionary<string, int>();
// Helper function to calculate the minimum cost
int DFS(IList<int> currNeeds)
{
// Convert current needs to a string key for memoization
var key = string.Join(",", currNeeds);
// If we have already computed the result for this set of needs, return it
if (memo.ContainsKey(key))
{
return memo[key];
}
// Base case: Calculate the cost without any special offers
int minCost = 0;
for (int i = 0; i < currNeeds.Count; i++)
{
minCost += currNeeds[i] * price[i];
}
// Try each special offer and see if it can be applied
foreach (var offer in special)
{
// Check if we can apply this offer
var valid = true;
var newNeeds = new List<int>(currNeeds.Count);
for (var i = 0; i < currNeeds.Count; i++)
{
if (currNeeds[i] < offer[i])
{
valid = false;
break;
}
newNeeds.Add(currNeeds[i] - offer[i]);
}
// If the offer is valid, recursively calculate the cost after applying the offer
if (valid)
{
minCost = Math.Min(minCost, offer[offer.Count - 1] + DFS(newNeeds));
}
}
// Store the result in memoization dictionary and return it
memo[key] = minCost;
return minCost;
}
// Start the DFS with the initial needs
return DFS(needs);
}
}