洛谷题面传送门

考虑一个平凡的 DP:我们设 \(dp_i\) 表示前 \(i\) 辆车一来一回所需的最小时间。

注意到我们每次肯定会让某一段连续的火车一趟过去又一趟回来,故转移可以枚举上一段结束位置,设为 \(j\),那么有转移

\[dp_i=\min\limits_{j}\{\max(dp_j+i-j-1,a_i)+2s+i-j-1\}
\]

在这里我们不妨假设 \(a_i<a_{i+1}\),这个可以通过从左到右扫一遍并执行 \(a_i\leftarrow\max(a_{i-1}+1,a_i)\) 实现。

稍微解释一下上面的式子,由于一趟来回,那么我们肯定会让前面的车都等到第 \(i\) 辆车到达对面后再返回,而第 \(i\) 辆车发车的时间是 \(\max(dp_j+j-i-1,a_i)\),因此第 \(i\) 辆车到达对面的最早时间就是 \(\max(dp_j+j-i-1,a_i)+s\)。而全部 \(j-i+1\) 辆车返程的时间又是 \(s+j-i+1\),总时间就是 \(\max(dp_j+j-i-1,a_i)+2s+j-i-1\)。

如何优化?考虑单调队列。我们考虑拆 \(\max\)。如果 \(dp_j+i-j-1\ge a_i\),也就是 \(dp_j-j\ge a_i-i+1\),\(\max\) 会取到 \(dp_j+i-j-1\),此时 \(dp_j+2s+2i-2j-2\leftarrow dp_i\),我们维护 \(dp_j-2j\) 的最大值即可实现,具体来说,根据 \(dp\) 数组的实际含义,有 \(dp_j-j\) 是单调不降的,因此我们考虑维护一个 \(dp_j-j\) 递增,\(dp_j-2j\) 递减的单调队列,每次 pop 掉队首直到队首元素符合 \(dp_j-j\ge a_i-i+1\)​ 然后用它更新答案即可。

如果 \(dp_j+i-j-1<a_i\),那么 \(a_i+2s+i-j-1\leftarrow dp_i\),因此我们只用维护 pop 出去的元素的 \(-j\) 的最小值即可,而由于我们是按照 \(j\) 递增的顺序将 \(j\)​​ 的贡献加入单调队列的,因此 \(-j\) 的最小值肯定在上一个被 pop 出去的元素处取到,直接更新答案即可。

时间复杂度线性。

感觉和 AGC 007D 有点像(

应该是 CSP 之前除了模拟赛之外刷的最后一道题了(

using namespace fastio;
const int MAXN=1e6;
int n,s,a[MAXN+5],q[MAXN+5],hd=1,tl=1;ll dp[MAXN+5];
ll calc(int x,int y){return max(1ll*a[y],dp[x]+y-x-1)+2*s+y-x-1;}
int main(){
read(n);read(s);a[0]=-1;
for(int i=1;i<=n;i++) read(a[i]);
for(int i=1;i<=n;i++) a[i]=max(a[i-1]+1,a[i]);
memset(dp,63,sizeof(dp));dp[0]=0;
for(int i=1;i<=n;i++){
while(hd<tl&&dp[q[hd]]-q[hd]<a[i]-i+1) ++hd;
if(hd<=tl) chkmin(dp[i],calc(q[hd],i));
if(hd>1) chkmin(dp[i],calc(q[hd-1],i));
while(hd<tl&&dp[q[tl]]-2*q[tl]>=dp[i]-2*i) --tl;
q[++tl]=i;
}
printf("%lld\n",dp[n]);
return 0;
}

洛谷 P3580 - [POI2014]ZAL-Freight(单调队列优化 dp)的更多相关文章

  1. 2018.09.26洛谷P3957 跳房子(二分+单调队列优化dp)

    传送门 表示去年考普及组的时候失了智,现在看来并不是很难啊. 直接二分答案然后单调队列优化dp检验就行了. 注意入队和出队的条件. 代码: #include<bits/stdc++.h> ...

  2. 洛谷 P3957 跳房子 —— 二分答案+单调队列优化DP

    题目:https://www.luogu.org/problemnew/show/P3957 先二分一个 g,然后判断: 由于转移的范围是一个区间,也就是滑动窗口,所以单调队列优化: 可以先令队尾为 ...

  3. 洛谷P1725琪露诺(单调队列优化dp)

    P1725 琪露诺 题目描述 在幻想乡,琪露诺是以笨蛋闻名的冰之妖精.某一天,琪露诺又在玩速冻青蛙,就是用冰把青蛙瞬间冻起来.但是这只青蛙比以往的要聪明许多,在琪露诺来之前就已经跑到了河的对岸.于是琪 ...

  4. BZOJ_3831_[Poi2014]Little Bird_单调队列优化DP

    BZOJ_3831_[Poi2014]Little Bird_单调队列优化DP Description 有一排n棵树,第i棵树的高度是Di. MHY要从第一棵树到第n棵树去找他的妹子玩. 如果MHY在 ...

  5. 【bzoj3831】[Poi2014]Little Bird 单调队列优化dp

    原文地址:http://www.cnblogs.com/GXZlegend/p/6826475.html 题目描述 In the Byteotian Line Forest there are   t ...

  6. 洛谷p1725 露琪诺 单调队列优化的DP

    #include <iostream> #include <cstdio> #include <cstring> using namespace std; int ...

  7. bzoj3831 [Poi2014]Little Bird 单调队列优化dp

    3831: [Poi2014]Little Bird Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 505  Solved: 322[Submit][ ...

  8. 【BZOJ】4721: [Noip2016]蚯蚓 / 【洛谷】P2827 蚯蚓(单调队列)

    Description 本题中,我们将用符号[c]表示对c向下取整,例如:[3.0」= [3.1」=[3.9」=3.蛐蛐国最近蚯蚓成灾了!隔壁跳 蚤国的跳蚤也拿蚯蚓们没办法,蛐蛐国王只好去请神刀手来帮 ...

  9. 洛谷P3195 [HNOI2008]玩具装箱TOY(单调队列优化DP)

    题目描述 P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维容器中.P教授有编号为1...N的N件玩具, ...

随机推荐

  1. 4.14——208. 实现 Trie (前缀树)

    前缀树(字典树)是经典的数据结构,以下图所示: 本来处理每个节点的子节点集合需要用到set,但是因为输入规定了只有26个小写字母,可以直接用一个[26]的数组来存储. 关于ASCII代码: Java ...

  2. 在 ASP.NET Core Web API中使用 Polly 构建弹性容错的微服务

    在 ASP.NET Core Web API中使用 Polly 构建弹性容错的微服务 https://procodeguide.com/programming/polly-in-aspnet-core ...

  3. 痞子衡嵌入式:超级下载算法RT-UFL v1.0在Keil MDK下的使用

    痞子衡主导的"学术"项目 <RT-UFL - 一个适用全平台i.MXRT的超级下载算法设计> v1.0 版发布近 4 个月了,部分客户已经在实际项目开发调试中用上了这个 ...

  4. 关于tkinter

    tkinter介绍 tkinter是python自带的GUI库,是对图形库TK的封装tkinter是一个跨平台的GUI库,开发的程序可以在win,linux或者mac下运行 组件概念 一个窗口中任意内 ...

  5. the Agiles Scrum Meeting 9

    会议时间:2020.4.17 20:00 1.每个人的工作 今天已完成的工作 个人结对项目增量开发组:基本实现个人项目创建.仓库自动分配,修复bug issues: 增量组:准备评测机制,增加仓库自动 ...

  6. Vue报错 type check failed for prop “xxx“. Expected String with value “xx“,got Number with value ‘xx‘

    vue报错    [Vue warn]: Invalid prop: type check failed for prop "name". Expected String with ...

  7. netty中使用protobuf实现多协议的消息

    在我们使用 netty 的过程中,有时候为了高效的传输数据,经常使用 protobuf 进行数据的传输,netty默认情况下为我们实现的 protobuf 的编解码,但是默认的只能实现单个对象的编解码 ...

  8. Noip模拟67 2021.10.3

    还是困,不过已经可以用脑子思考问题了 T1 数据恢复 没啥明确的算法,可以说是贪心? 考虑部分分, 链的直接扫, 对于菊花的发现只要根节点在第一个,剩下的点位置不重要 那么按照$a/b$排序,扫一遍就 ...

  9. numpy数组的计算

    1.数组的形状 查看数组的形状: import numpy as np a = np.array([[1, 2, 3, 4, 5], [5, 6, 7, 8, 9]]) print(a.shape) ...

  10. vcs(UST)Undefined System Task Call

    转载:VCS求助啊 - 微波EDA网 (mweda.com) Error-[UST] Undefined System Task Call../../path/bench/path.v, 51Unde ...