赞
踩
题目难度: 中等
在一个火车旅行很受欢迎的国度,你提前一年计划了一些火车旅行。在接下来的一年里,你要旅行的日子将以一个名为 days 的数组给出。每一项是一个从 1 到 365 的整数。
火车票有三种不同的销售方式:
通行证允许数天无限制的旅行。 例如,如果我们在第 2 天获得一张为期 7 天的通行证,那么我们可以连着旅行 7 天:第 2 天、第 3 天、第 4 天、第 5 天、第 6 天、第 7 天和第 8 天。
返回你想要完成在给定的列表 days 中列出的每一天的旅行所需要的最低消费。
days = [1,4,6,7,8,20], costs = [2,7,15]
11
例如,这里有一种购买通行证的方法,可以让你完成你的旅行计划:
你总共花了 $11,并完成了你计划的每一天旅行。
days = [1,2,3,4,5,6,7,8,9,10,30,31], costs = [2,7,15]
17
例如,这里有一种购买通行证的方法,可以让你完成你的旅行计划:
你总共花了 $17,并完成了你计划的每一天旅行。
class Solution: def mincostTickets(self, days: List[int], costs: List[int]) -> int: dp = [] for i in range(len(days)): # 当前日期买1天票的情况 mncost = costs[0] if i == 0 else dp[-1] + costs[0] # 当前日期买了7天或30天票的情况 # 需要找到之前的不在当前时间窗口的日期 for ci, duration in ((1, 7), (2, 30)): # ci表示当前duration在costs数组的下标 for j in range(i)[::-1]: if days[i] - days[j] >= duration: # 意味着在第j个日期和当前日期不在同一个时间窗口内, 如果当前日期想买这个时间窗口票的话, 必须在那个日期基础上加上当前时间窗口的价格 mncost = min(mncost, dp[j] + costs[ci]) break else: # 说明前面的所有日期和当前日期都在同一时间窗口内, 直接买一张票就能全部覆盖 mncost = min(mncost, costs[ci]) dp.append(mncost) return dp[-1]
class Solution { public: int mincostTickets(vector<int>& days, vector<int>& costs) { int num_days = days.size(); vector<int> dp(num_days, 0); unordered_map<int, int> costs_map = {{1, 7}, {2, 30}}; for (int i = 0; i < num_days; ++i) { dp[i] = i > 0 ? (dp[i-1] + costs[0]) : costs[0]; for (auto& entry : costs_map) { bool in_range = true; auto index = entry.first; auto duration = entry.second; for (int j = i-1; j >= 0; --j) { if (days[i] - days[j] >= duration) { dp[i] = min(dp[i], dp[j] + costs[index]); in_range = false; break; } } if (in_range) { dp[i] = min(dp[i], costs[index]); } } } return dp[num_days-1]; } };
我的公众号: 每日精选算法题, 欢迎大家扫码关注~
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/398293
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。