一道好题
首先肯定是DP,考虑如何DP
我们发现可以尝试按照乘坐的列车编号的序列进行DP
设表示某种列车序列,最后一趟车是第个班次的最小花费
那么显然有
打开之后发现有和的乘积项,所以想到斜率优化
移项后变成,其中要求
考虑如何优化,我们肯定要将原来的列车班次进行某种排序,然后进行线性DP
这里肯定要么按照排序,要么按照排序(因为时间这一维度是具有单调性,而如果按照或者排序,由于就很难发现单调性)
我们先按照排序,不难发现是维护斜率单调递增
我们把每一个已经DP好了的按照其值放在对应的单调队列里面(也就是一共有个单调队列),在计算某一个的时候,我们只需要在对应的单调队列里面去查找即可
这样就对了吗?
其实是不行的。首先,显然不一定单调,所以我们要用二分,而且还要先用二分在这个单调队列里面查找出来满足的位置;其次,可能存在一种情况,如下

如图所示,号点的进入会将号点弹出去,但有可能号点是满足的最大位置,那么号点是有可能成为最优决策的
那么解决这个的办法是什么?我们就选择不弹出某个点,而是记录某个点如果进行普通的斜率优化的单调队列的话,他的前一个点是哪一个点,设为。假设新进来一个点,我们就比较这个点和当前单调队列的最后一个点的斜率与当前单调队列的最后一个点和其(设这个点为)的斜率大小来决定是否“弹出”当前单调队列的最后一个点(注意我们并不会真的弹出当前单调队列的最后一个点);如果要“弹出”,那么就继续比较新进来的这个点和的斜率与和其的斜率来决定是否“弹出”,依次类推。不难发现时间复杂度仍然正确(相当于还是每个点最多进队出队一次)。但是这个做法对后面的二分查找就很麻烦了,我只想到了倍增
提醒一下,如果某一趟班次的,这一趟班次不一定非要放在第一个,我们可以先做其他车,最后回到号站,然后再作这一趟班次,可能时间会更优
以上解法是对排序,但是代码很难写,那么我们尝试对排序
此时对排序之后,就解决了斜率不是单调递增的问题(指解决的这个问题:“首先,显然不一定单调,所以我们要用二分”)
然后仍然需要满足
第一个条件的处理跟之前一样,就不赘述了
问题是第二个条件的处理
我们想的是某一时刻,当我们更新的时候,对应的单调队列的所有点都可以用,就可以忽略第二个条件了
为了达到这种效果,我们更新了之后,不要马上把插入其对应的单调队列,而是选择放到一个桶里面(对应这一趟班次的值);然后我们在每次更新之前,先把所有小于等于的桶里面的班次全部插入到对应的单调队列里面就好了
update 2024.7.6
重新做一遍这个题目,已经把状态给想出来,但是却没能想出按照某种顺序排序从而进行线性DP(想的是利用记忆化搜索),就是因为没有写出所有限制条件,所以以后一定要把所有限制条件写出然后排序线性DP啊
说一下心路历程:
最开始设表示在时刻从号站到号站的最小烦躁值,显然复杂度爆炸,但是在推导的过程中发现我们似乎不用设置时刻因为小猫不能自己走,只能通过坐车的方式到达站,所以时刻的信息可以通过两个班次的值来反映,于是改变状态设表示从号站到班次的起/终点的最小烦躁值(根据上文分析,由于时间反映在班次里面,所以不妨认为这个烦躁值是在这个班次的时刻达到的),不难发现(因为坐车不增加烦躁值),所以可以设出
update 2024.9.11
重新做了一遍,做出来了
当然中间的转移也可以用李超线段树,但是也要利用“不要更新完就插入”的技巧
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构