📝题目
1 | 在一个火车旅行很受欢迎的国度,你提前一年计划了一些火车旅行。在接下来的一年里,你要旅行的日子将以一个名为 days 的数组给出。每一项是一个从 1 到 365 的整数。 |
📝思路
主干思路:
- 今天不需要出门,不用买票
- 今天如果要出门,需要买几天?
- 看往后几天(最多30天内)要不要出门
- 30天内都没有要出行的,那只买今天就好
- 有要出门的(不同决策)
- 这次 和 后面几次 分开买更省
- 这次 和 后面几次 一起买更省
- 看往后几天(最多30天内)要不要出门
上述思路显而易见,最关键在于:「今天买多少,得看后几天怎么安排」,即「前面依赖后面」——从后向前来买。
如图所示,例如:$days = [1,4,6,7,8,20]$
- 第 21 及以后的日子都不需要出门,不用买票
- 第 20 需要出门,需要买几天?
- 不考虑 20 之前要不要出门,否则与思路相违背
- 第 20 之后没有出门日,故买「一天」的 costs[0] 最省钱。
- 第 9 - 19 不需要出门,则不用买
- 第 8 需要出门,需要买几天?
- 往后(只需看往后30天)有出门的需求
- 决策1:买一天期,后面的不包
- 决策2:买七天期,包到第 8 + 7 - 1 天,第 8 + 7 天往后的不包
- 决策3:买三十天期,包到第 8 + 30 - 1 天,第 8 + 30 天往后的不包
- 可见,决策3 包三十天期的话,第 20 可不用花钱
- 往后(只需看往后30天)有出门的需求
- …
- 抽象,定义状态:dp[i] 为第 i 天开始,累计所需最小费用
1
2
3dp[i] = min(决策1, 决策2, 决策3);
= min(c[0] + 1天后不包, c[1] + 7天后不包, c[2] + 30天不包);
= min(c[0] + dp[i + 1], c[1] + dp[i + 7], c[2] + dp[i + 30]);
📝题解
1 | int mincostTickets(vector<int>& days, vector<int>& costs) { |
All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.