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
.
Note:
1 <= days.length <= 365
1 <= days[i] <= 365
days is in strictly increasing order.
costs.length == 3
1 <= costs[i] <= 1000
题目大意就是给定这个人想要出行的日子(1~365
中的某些天),提供三种出行的票—支持1、7、30天游玩的票种,如何购票最便宜?
解题思路:动态规划
解题作者:LotusPanda
动态规划问题最重要是3步:
- 明确创建怎样的dp数组
- 初始化dp数组
- 明确动态转移方程
对于本题不难想到应该用一个数组存储到当前某一天需要花费的最少费用,这里为了下标和天数对应,dp数组的长度选择 days 中最后一个天数多加 1 个长度,因为开始没有费用,所以初始化为 0 ,之后开始对 dp 数组进行更新,那么每到达一个位置首先考虑当前天数是否在days 中,如果不在那花费的费用肯定和它前一天花费的最少费用相同(这里用一个 idx 指标指示应该处理哪一个天数,这样就不必用 if i in days 这样的语句判断天数是否需要处理了,可以让程序快一些),如果在的话,我们就要从三种购买方式中选择一种花费费用最少的,即你想到达第 i 天,你需要从 i 的前1或7或30天的后一位置花费对应cost[0]、cost[1]、cost[2]的钱才能到第 i 天。
具体细节见代码。
class Solution:
def mincostTickets(self, days: List[int], costs: List[int]) -> int:
# 创建一个以最后一天为大小的数组,+1是填补第0个位置
# 该数组用来记录每一天的花费
dp = [0 for _ in range(days[-1]+1)]
days_inx = 0
# 遍历days,如果这一天没去,那么dp[i]=dp[i-1];
# 如果去了,就判断如果从这一天起前j天买了j天的套票,三种的最小值
for i in range(len(dp)):
if i == days[days_inx]:
dp[i] = min(dp[max(0,i-1)] + costs[0],dp[max(0,i-7)] + costs[1],dp[max(0,i-30)] + costs[2])
days_inx +=1
else:
dp[i] = dp[i-1]
return dp[-1]
看了熊猫大侠的思路,瞬间清醒,太赞了!