洛谷题面传送门

考虑一个平凡的 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. 力扣 - 剑指 Offer 39. 数组中出现次数超过一半的数字

    题目 剑指 Offer 39. 数组中出现次数超过一半的数字 思路1(排序) 因为题目说一定会存在超过数组长度一半的一个数字,所以我们将数组排序后,位于length/2位置的一定是众数 代码 clas ...

  2. Django Model字段加密的优雅实现

    早前的一篇文章Django开发密码管理表实例有写我们写了个密码管理工具来实现对密码的管理,当时加密解密的功能在view层实现,一直运行稳定所以也没有过多关注实现是否优雅的问题.最近要多加几个密码表再次 ...

  3. Java:并发笔记-06

    Java:并发笔记-06 说明:这是看了 bilibili 上 黑马程序员 的课程 java并发编程 后做的笔记 5. 共享模型之无锁 本章内容 CAS 与 volatile 原子整数 原子引用 原子 ...

  4. Hadoop的安装与部署

    一.硬件及环境 服务器:3台,IP分别为:192.168.100.105.192.168.100.110.192.168.100.115 操作系统:Ubuntu Server 18.04 JDK:1. ...

  5. 记录一次因subprocess PIPE 引起的线上故障

    sence:python中使用subprocess.Popen(cmd, stdout=sys.STDOUT, stderr=sys.STDERR, shell=True) ,stdout, stde ...

  6. void * 是什么?

    最近遇到void *的问题无法解决,发现再也无法逃避了(以前都是采取悄悄绕过原则),于是我决定直面它. 在哪遇到了? 线程创建函数pthread_create()的最后一个参数void *arg,嗯? ...

  7. Discovery直播 | 3D“模”术师,还原立体世界——探秘3D建模服务

    通过多张普通的照片重建一个立体逼真的3D物体模型,曾经靠想象实现的事情,现在, 使用HMS Core 3D建模服务即可实现! 3D模型作为物品在数字世界中的孪生体,用户可以自己拍摄.建模并在终端直观感 ...

  8. 刷题日记-JZ25合并有序链表

    合并有序链表 递归方式合并链表pHead1,pHead2 base case是 pHead1为空或者pHead2为空 递归方式是 如果pHead1->val < pHead2->va ...

  9. 访问kubernetes CRD的几种方式

    访问kubernetes CRD的几种方式 最近在使用代码操作VictoriaMetrics Operator的CRD资源的过程中,探究了集中访问CRD资源的方式.下面以VictoriaMetrics ...

  10. Python打包成exe可执行文件

    Python打包成exe可执行文件 安装pyinstaller pyinstaller打包机制 Pyinstaller打包exe 总结命令 可能会碰到的一些常见问题 我们开发的脚本一般都会用到一些第三 ...