前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【DP】983. Minimum Cost For Tickets

【DP】983. Minimum Cost For Tickets

作者头像
echobingo
发布2019-05-14 10:13:14
3110
发布2019-05-14 10:13:14
举报
文章被收录于专栏:Bingo的深度学习杂货店
问题描述:

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:

代码语言:javascript
复制
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:
代码语言:javascript
复制
Input: days = [1,4,6,7,8,20], costs = [2,7,15]
Output: 11
Explanation: 
For example, here is one way to buy passes that lets you travel your travel plan:
On day 1, you bought a 1-day pass for costs[0] = $2, which covered day 1.
On day 3, you bought a 7-day pass for costs[1] = $7, which covered days 3, 4, ..., 9.
On day 20, you bought a 1-day pass for costs[0] = $2, which covered day 20.
In total you spent $11 and covered all the days of your travel.
Example 2:
代码语言:javascript
复制
Input: days = [1,2,3,4,5,6,7,8,9,10,30,31], costs = [2,7,15]
Output: 17
Explanation: 
For example, here is one way to buy passes that lets you travel your travel plan:
On day 1, you bought a 30-day pass for costs[2] = $15 which covered days 1, 2, ..., 30.
On day 31, you bought a 1-day pass for costs[0] = $2 which covered day 31.
In total you spent $17 and covered all the days of your travel.
Note:
代码语言:javascript
复制
1 <= days.length <= 365
1 <= days[i] <= 365
days is in strictly increasing order.
costs.length == 3
1 <= costs[i] <= 1000
解题思路:

很显现这是一道动态规划的问题,而且很容易想到用 dp[i] 表示第 i 天累计的最少费用。而问题的关键在于寻找转移方程式,然后更新 dp[i],得出的 dp[N] 就是最后的的答案。

这道题如果眼光受限于给定的列表中的天数,寻找转移方程会比较困难。较为简单的一种方法是,把没有出现的天数也考虑在内,如果某天没有在列表中出现,那么费用不用更新,即 dp[i] = dp[i - 1], if i is not days这样做的好处是,时间可以连续,保证了 dp[i] 在每一天都有值,便于后续的转移方程的推导。

现在考虑,如果某一天 i 在 days 中,即 i is in days 的情况。因为 在计算到第 i 天的费用时,前 i - 1 天我们已经求出了,而且是最优解。

以 days = [1,2,4,7,8], costs = [2,7,15] 为例,我们容易求得 dp[0] = 0 (第0天他花费为0),dp[1] = 2, dp[2] = dp[2-1] + cost[0] = 4, dp[3] = dp[3-1] = 4(没有出现的天数), dp[4] = dp[4-1] + cost[0] = 6, dp[5] = dp[5-1] = 6(没有出现的天数), dp[6] = dp[6-1] = 6(没有出现的天数), 而 dp[7] = min(dp[7-1] + cost[0], dp[7-7] + cost[1]) = min(8, 0+7) = 7, dp[8] = min(dp[8-1] + cost[0], dp[8-7] + cost[1]) = min(7+2, 2+7) = 9

观察到规律,第 i 天的费用取决于 dp[i - 1] + cost[0]、dp[i - 7] + cost[1]、dp[i - 1] + cost[2] 中的最小值,即 dp[i] = min(dp[i - 1] + cost[0], dp[i - 7] + cost[1], dp[i - 1] + cost[2])

因此,只需要遍历小于等于 days[-1] 的所有天数,依次求得 dp[i],最终 dp[days[-1]] 就是最后的答案。

如果把 days 变成集合 set,在查找的时候,时间复杂度为 O(1),因此整体时间复杂度为 O(n)。

Python3 实现:
代码语言:javascript
复制
class Solution:
    def mincostTickets(self, days, costs):
        dp = [0] * 366
        days_set = set(days)  # 变成集合,后面查找的时间复杂度为 O(1)
        for i in range(1, days[-1] + 1):
            if i not in days_set:
                dp[i] = dp[i - 1]
            else:
                dp[i] = min(dp[i - 1] + costs[0], dp[i - 7] + costs[1], dp[i - 30] + costs[2])
        return dp[days[-1]]

print(Solution().mincostTickets([1,4,6,7,8,20], [2,7,15]))  # 11
print(Solution().mincostTickets([1,2,3,4,5,6,7,8,9,10,30,31], [2,7,15]))  # 17
print(Solution().mincostTickets([1,4,6,7,8,20], [7,2,15]))  # 6
print(Solution().mincostTickets([1,2,3,4,6,8,9,10,13,14,16,17,19,21,24,26,27,28,29], [3,14,50]))  # 50
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019.04.30 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 问题描述:
    • Example 1:
      • Example 2:
        • Note:
        • 解题思路:
        • Python3 实现:
        相关产品与服务
        对象存储
        对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档