Problem
In a country popular for train travel, you have planned some train travelling one year in advance. The days of the year that you will travel is given as an array days. Each day is an integer from 1 to 365.
Train tickets are sold in 3 different ways:
- a 1-day pass is sold for
costs[0]dollars; - a 7-day pass is sold for
costs[1]dollars; - 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: day 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:
1 | Input: days = [1,4,6,7,8,20], costs = [2,7,15] |
Example 2:
1 | Input: days = [1,2,3,4,5,6,7,8,9,10,30,31], costs = [2,7,15] |
Note:
1 <= days.length <= 3651 <= days[i] <= 365daysis in strictly increasing order.costs.length == 31 <= costs[i] <= 1000
Analysis
这道题一看就是用动态规划了。因为要求的是最少的价钱,后面买不买是取决于前面的决定,这就是典型的动态规划。状态转移主要有两个问题要考虑,一个是要不要买,另一个是买哪个旅行。
先看第一个问题,当前买不买是要看当天是否需要旅行,如果不需要的话,就和前一天的状态一致即可,因为不需要旅行的话就不需要考虑这一天的购入。
第二个问题会比较麻烦,因为ticket有三种,1天、7天和30天。所以对于某一天需要旅行的话,可以有三个选择:
- 前一天的cost加上1天的ticket;
- 7天前的cost加上7天的ticket;
- 30天前的cost加上30天的ticket
Solution
上面的分析就是整个状态转移的过程了。当然在coding过程中还是有一些要注意的。首先是如果知道某一天是否需要旅游,我们可以在初始化dp数组的时候,把不需要旅游的dp初始化为MAX_INT,这样就很容易解决第一个问题。
在解决第二个问题的时候,会有边界的情况出现,这个时候需要防止越界的情况出现。比如在第10天的时候计算30天前,就应该用第一天的cost来计算。
Code
1 | class Solution { |
Summary
这道题的本质还是最基本的动态规划,不过在这个基础上加上了多个选择,还有一些边界情况需要处理,总的来说难度不大。这道题的分析到这里,谢谢!