LeetCode算法-983. Minimum Cost For Tickets[medium]

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]

看了熊猫大侠的思路,瞬间清醒,太赞了!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值