AlgoInsight

DSA problem

Minimum Cost For Tickets

MediumUnbounded KnapsackPattern: Unbounded Knapsacktop600AmazonGoogleMicrosoftUberBloomberg

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 that costs costs[0], a 7-day pass that costs costs[1], and a 30-day pass that costs costs[2]. The passes allow consecutive travel: for example, if you get a 7-day pass on day 2, you can travel for 7 consecutive days (days 2 through 8). Return the minimum number of dollars you need to travel every day in the given list of days.

This is an unbounded-knapsack variant: at every travel day you decide which of three pass types to "buy" (each can be used unlimited times across the year), and the goal is to minimize the total cost. Although passes give you 1, 7, or 30 consecutive days of coverage, a clean reformulation lets us iterate over each calendar day and decide the cheapest way to cover up to and including that day.

Let dp[d] be the minimum cost to cover all travel days up to and including calendar day d, for d from 0 to the last travel day. The base case is dp[0] = 0. If day d is NOT in the travel set, we owe nothing extra for day d, so dp[d] = dp[d - 1]. If day d IS a travel day, we must have just bought one of the three passes that covers day d, giving dp[d] = min(dp[d - 1] + costs[0], dp[max(0, d - 7)] + costs[1], dp[max(0, d - 30)] + costs[2]).

To check membership efficiently, convert days into a hash set first so each lookup is O(1). The total runtime is O(D) where D is the last travel day, and the extra space is O(D) for the DP table plus O(len(days)) for the set. The answer is dp[last_day].

Examples

Example 1
Input: days = [1,4,6,7,8,20], costs = [2,7,15]
Output: 11
Explanation: Buy a 1-day pass on day 1 (cost 2), a 7-day pass on day 3 covering days 3-9 (cost 7), and a 1-day pass on day 20 (cost 2). Total = 2 + 7 + 2 = 11.
Example 2
Input: days = [1,2,3,4,5,6,7,8,9,10,30,31], costs = [2,7,15]
Output: 17
Explanation: Buy a 30-day pass on day 1 to cover days 1-30 (cost 15), then a 1-day pass on day 31 (cost 2). Total = 17.
Example 3
Input: days = [1], costs = [2,7,15]
Output: 2
Explanation: A single 1-day pass on day 1 is cheapest at cost 2.

Constraints

3 hints and a full solution walkthrough with step-by-step visualizations are available in the practice editor.

dynamic-programmingunbounded-knapsackarrayhash-table

Browse all DSA problems