983. Minimum Cost For Tickets
題目網址:https://leetcode.cn/problems/minimum-cost-for-tickets/
題意:給一整數 array
days代表旅行的日子, 其中1 ≤ days[i] ≤ 365。車票有三種不同的銷售方式 :
- 一張 1-day 通行證的售價為
costs[0]- 一張 7-day 通行證的售價為
costs[1]- 一張 30-day 通行證的售價為
costs[2]通行證允許數天無限制的旅行。例如, 如果我們在第
2天獲得一張 7-day 的通行證, 則可以連著旅行7天:第2天、第3天、第4天、第5天、第6天、第7天和第8天。返回滿足
days中每一天都旅行所需的最低花費。注意:
days是嚴格遞增的。

Solution:
想法:利用 DP
1. 定義狀態:
dp[i]:代表旅行到第i天所需的最小花費2. 得到轉移方程:
- 若
i not in days:也就是第i天實際上不用旅行, 因此直接使用上一次的狀態即可
➔dp[i] = dp[i - 1]i in days:有三種選擇, 取其中最小的
- 第
i天購買 1-day 通行證, 總花費 = 前i - 1天的花費 +costs[0]
➔dp[i] = dp[i - 1] + costs[0]- 第
i - 6天購買 7-day 通行證, 總花費 = 前i - 7天的花費 +costs[1]
➔dp[i] = dp[i - 7] + costs[1]- 第
i - 29天購買 30-day 通行證, 總花費 = 前i - 30天的花費 +costs[2]
➔dp[i] = dp[i - 30] + costs[2]3. 初始化:
dp[0]:旅行到第0天所需的最小花費為04. 你可能會問:「為什麼不能用其他的組合?e.g. 第
i - 2天時購買 7-day 的通行證, 這樣一樣可以 cover 到第i天」
定理:當
j < i時,dp[j] ≤ dp[i]恆成立反證法:假設
dp[j] > dp[i], 那第j天時就使用第i天的方案, 剩下的天數寧可浪費掉, 這樣一來dp[j] = dp[i]➔ 與一開始的假設dp[j] > dp[i]相互矛盾, 故dp[j] ≤ dp[i]由上述定理可得知,
dp[i - 7] ≤ dp[i - 2], 故只需考慮dp[i - 7] + costs[1]就好, 而不需考慮dp[i - 2] + costs[1]
class Solution { |
- time:$O(1)$ ➔ $O(365)$, 因為 for loop 取決於
days.back() - space:$O(1)$ ➔ $O(365)$, 因為
dp的大小取決於days.back()
本部落格所有文章除特別聲明外,均採用 CC BY-NC-SA 4.0 許可協議。轉載請註明來自 Zako's Blog!
評論