DYNP-P4

Season tickets

Practice 4 of 9Dynamic programming8 tests

The problem

You know the days on which you will travel by train: days, a rising list of different whole numbers. The railway sells passes, given as (length, price): a pass bought on day d lets you travel on days d, d + 1, …, d + length − 1. You may buy any pass any number of times. Return the least total price that lets you travel on every day in days.

season_tickets([1, 4, 6, 7, 8, 20],
               [(1, 2), (7, 7), (30, 15)])
# 11: a 1-day ticket on day 1, a 7-day pass
# from day 4 (covers 4 to 10), a 1-day on day 20

Limits

  • Up to 100,000 travel days, each from 1 to 2,000,000,000; up to 6 passes, each with a length of at least 1. A table with one entry per calendar day is far too big.
  • Aim for about O(n · p · log n) for n trips and p passes. bisect is allowed.
  • Python stops at about 1,000 nested calls, and a function wrapped in functools.cache stops after a few hundred in the browser. The big tests need far more than that, so memoised recursion fails them. Fill a table with a loop (lesson 3).

Builds on DYNP-4 One-dimensional DP.

Continue on a laptop

Practice runs Python in the browser and needs a keyboard and a wider screen. Read the problem and open hints here, then write your solution on a laptop. Progress is saved per browser for now, so hints opened here stay on this device.

Need a hint?0 of 3 opened

  1. Hint 1Nudge
  2. Hint 2Approach Open hint 1 first
  3. Hint 3Pseudocode Open hint 2 first
  4. Worked solutionlast resort Opens after all 3 hints
Python waits for a wider screensolution.py

Ctrl + Enter runs the tests. Tab indents; press Esc, then Tab, to leave the editor.

8 tests, not run yet
Test results
#TestResultReads · time
1The exampleNot run
2No tripsNot run
3A long pass can be cheaperNot run
4Far apartNot run
5The last day of a passNot run
6Passes in any orderNot run
7100,000 trips in clustersNot run
8100,000 trips in a rowNot run