Taro Logo

Minimum Cost For Tickets

Medium
4 views
2 months ago

You have planned some train traveling one year in advance. The days of the year in which you will travel are given as an integer array days. Each day is an integer from 1 to 365.

Train tickets are sold in three different ways:

  • a 1-day pass is sold for costs[0] dollars,
  • a 7-day pass is sold for costs[1] dollars, and
  • a 30-day pass is sold for costs[2] dollars.

The passes allow that many days of consecutive travel.

  • For example, if we get a 7-day pass on day 2, then we can travel for 7 days: 2, 3, 4, 5, 6, 7, and 8.

Return the minimum number of dollars you need to travel every day in the given list of days.

Example 1:

Input: days = [1,4,6,7,8,20], costs = [2,7,15]
Output: 11

Example 2:

Input: days = [1,2,3,4,5,6,7,8,9,10,30,31], costs = [2,7,15]
Output: 17

Solve this problem using dynamic programming.

Sample Answer
class Solution:
    def mincostTickets(self, days: List[int], costs: List[int]) -> int:
        n = len(days)
        dp = {}

        def solve(i):
            if i == n:
                return 0
            if i in dp:
                return dp[i]

            # Option 1: Buy a 1-day pass
            cost1 = costs[0] + solve(i + 1)

            # Option 2: Buy a 7-day pass
            j = i
            while j < n and days[j] < days[i] + 7:
                j += 1
            cost7 = costs[1] + solve(j)

            # Option 3: Buy a 30-day pass
            j = i
            while j < n and days[j] < days[i] + 30:
                j += 1
            cost30 = costs[2] + solve(j)

            dp[i] = min(cost1, cost7, cost30)
            return dp[i]

        return solve(0)

Explanation:

  1. Problem Understanding: The problem asks us to find the minimum cost to travel on specific days, given the costs of 1-day, 7-day, and 30-day passes.
  2. Approach: We can use dynamic programming to solve this problem. We'll create a dp dictionary to store the minimum cost to travel from a given day onwards.
  3. solve(i) Function:
    • Base Case: If i reaches the end of the days array, it means we have covered all travel days, so the cost is 0.
    • Memoization: If the cost for day i is already computed and stored in dp, return it.
    • Recursive Calls: Explore three options:
      • Buy a 1-day pass: Add the cost of the 1-day pass and recursively call solve(i + 1) for the next day.
      • Buy a 7-day pass: Find the first day j that is more than 7 days from the current day i. Add the cost of the 7-day pass and recursively call solve(j).
      • Buy a 30-day pass: Find the first day j that is more than 30 days from the current day i. Add the cost of the 30-day pass and recursively call solve(j).
    • Return the minimum of the three options.

Example

For days = [1,4,6,7,8,20] and costs = [2,7,15], the code calculates the minimum cost recursively with memoization. It considers buying 1-day, 7-day, and 30-day passes at each travel day and chooses the option that results in the minimum total cost.

Big O Analysis

  • Time Complexity: O(N), where N is the number of travel days. This is because each day is visited only once due to memoization.
  • Space Complexity: O(N), where N is the number of travel days. This is due to the space used by the dp dictionary and the recursion stack.