# Solving Leetcode Interviews in Seconds with AI: Maximum Number of Events That Can Be Attended II


	# Introduction
	In this blog post, we will explore how to solve the LeetCode problem "1751" using AI. LeetCode is a popular platform for preparing for coding interviews, and with the help of AI tools like [Chatmagic](https://www.chatmagic.app), we can generate solutions quickly and efficiently - helping you pass the interviews and get the job offer without having to study for months.

	# Problem Statement
	> You are given an array of events where events[i] = [startDayi, endDayi, valuei]. The ith event starts at startDayi and ends at endDayi, and if you attend this event, you will receive a value of valuei. You are also given an integer k which represents the maximum number of events you can attend. You can only attend one event at a time. If you choose to attend an event, you must attend the entire event. Note that the end day is inclusive: that is, you cannot attend two events where one of them starts and the other ends on the same day. Return the maximum sum of values that you can receive by attending events.   Example 1:   Input: events = [[1,2,4],[3,4,3],[2,3,1]], k = 2 Output: 7 Explanation: Choose the green events, 0 and 1 (0-indexed) for a total value of 4 + 3 = 7. Example 2:   Input: events = [[1,2,4],[3,4,3],[2,3,10]], k = 2 Output: 10 Explanation: Choose event 2 for a total value of 10. Notice that you cannot attend any other event as they overlap, and that you do not have to attend k events. Example 3:   Input: events = [[1,1,1],[2,2,2],[3,3,3],[4,4,4]], k = 3 Output: 9 Explanation: Although the events do not overlap, you can only attend 3 events. Pick the highest valued three.   Constraints:  1 <= k <= events.length 1 <= k * events.length <= 106 1 <= startDayi <= endDayi <= 109 1 <= valuei <= 106  

	# Explanation
	Here's a breakdown of the optimal solution:

*   **Dynamic Programming with Memoization:** We use dynamic programming to explore all possible combinations of events. The state of the DP is defined by `(index, count)`, where `index` is the current event being considered and `count` is the number of events already attended. Memoization is crucial to avoid recomputing the same subproblems.
*   **Binary Search:** To efficiently find the next non-overlapping event after attending a given event, we perform a binary search on the sorted list of event start days. This allows us to quickly skip over events that conflict with the currently attended event.
*   **Sorting by End Time:** Sorting the events by their end times enables the binary search to work effectively. By sorting by end times, we guarantee that if `events[i]` and `events[j]` overlap and i<j, `events[j]` occurs after `events[i]` ends.

*   **Runtime Complexity:** O(k \* n \* log n), where n is the number of events and k is the maximum number of events that can be attended.
*   **Storage Complexity:** O(k \* n)

	
	# Code
	```python
	from bisect import bisect_left

def max_value(events, k):
    """
    Calculates the maximum sum of values that can be received by attending events.

    Args:
        events: A list of events, where events[i] = [startDayi, endDayi, valuei].
        k: The maximum number of events you can attend.

    Returns:
        The maximum sum of values that you can receive by attending events.
    """

    events.sort(key=lambda x: x[1])  # Sort events by end time
    n = len(events)
    dp = {}  # Memoization table (index, count) -> max_value

    def solve(index, count):
        if count == k or index == n:
            return 0

        if (index, count) in dp:
            return dp[(index, count)]

        # Option 1: Skip the current event
        skip = solve(index + 1, count)

        # Option 2: Attend the current event
        attend = events[index][2]  # Value of the current event

        # Find the next non-overlapping event using binary search
        next_event_index = bisect_left([events[i][0] for i in range(n)], events[index][1] + 1)

        attend += solve(next_event_index, count + 1)

        dp[(index, count)] = max(skip, attend)
        return dp[(index, count)]

    return solve(0, 0)
	```
			
