You are given a list of sorted integers days , where you must take the bus for on each day. Return the lowest cost it takes to travel for all the days.
There are 3 types of bus tickets.
1 day pass for 2 dollars
7 day pass for 7 dollars
30 day pass for 25 dollars
Constraints
n ≤ 100,000 where n is the length of days
Example 1
Input
days = [1, 3, 4, 5, 29]
Output
9
Explanation
The lowest cost can be achieved by purchasing a 7 day pass in the beginning and then a 1 day pass on the 29th day.
Example 2
Input
days = [1]
Output
2
前置知识
递归树
多指针
公司
暂无
暴力 DP
思路
定义专状态 dp[i] 为截止第 i + 1 天(包括)需要多少钱,因此答案就是 dp[n],其中 n 为 max(days),由于 day 是升序的,因此就是 day 最后一项。
使用两层暴力寻找。外层控制 i 天, 内层循环控制 j 天,其中 i <= j。每次我们只考虑进行一次操作:
买一张天数 2 的票
买一张天数 7 的票
买一张天数 25 的票
对于每一个 [i, j]对,我们对计算一遍,求出最小值就可以了。
代码:
class Solution:
def solve(self, days):
n = len(days)
prices = [2, 7, 25]
durations = [1, 7, 30]
dp = [float("inf")] * (n + 1)
dp[0] = 0
for i in range(1, n + 1):
for j in range(i, n + 1):
# 如何第 i + 1天到第 j 天的天数小于等于 2,那么我们就试一下在 i + 1 天买一张 2 天的票,看会不会是最优解。
# 7 和 25 的逻辑也是一样
return dp[-1]
代码
代码支持:Python3
Python3 Code:
class Solution:
def solve(self, days):
n = len(days)
prices = [2, 7, 25]
durations = [1, 7, 30]
dp = [float("inf")] * (n + 1)
# dp[i] 表示截止第 i + 1 天(包括)需要多少钱,因此答案就是 dp[n],其中 n 为 max(days),由于 day 是升序的,因此就是 day 最后一项。
dp[0] = 0
for i in range(1, n + 1):
for j in range(i, n + 1):
for price, duration in zip(prices, durations):
if days[j - 1] - days[i - 1] + 1 <= duration:
dp[j] = min(dp[j], dp[i - 1] + price)
return dp[-1]