P5017 [NOIP2018 普及组] 摆渡车

题目

P5017

思路

将实际问题抽象后,不难发现这是一个 区间 \(DP\)

我们不妨认为时间是一条数轴,每名同学按照到达时刻分别对应数轴上可能重合的点。安排车辆的工作,等同于将数轴分成若干个左开右闭段,每段的长度 \(\geqslant m\)。原本的等车时间之和,自然就转换成所有点到各自所属段右边界距离之和

转移: \(f_i=min\{f_j+\sum_{j<t_k\leq i} i-t_k\}\)\(,\) \(j\leq i-m\)

但是这样显然时间复杂度会超标

考虑使用前缀和优化掉那个大大的 \(\sum\)

之后,转移式可以这样写: \(f_i=min\{f_j+(cnt_i-cnt_j)*i-(sum_i-sum_j)\}\) \(,\) \(j\leq i-m\)

这里令 \(t=max\{t_i\}\) \(,\) \(1\leq i \leq n\),最终答案只需在 \(i \geqslant t\) 找最小的 \(f_i\) 即可。实际上,\([t, t+m)\) 包含了所有可能的答案。

此时考虑时间复杂度:\(O(n^2)\) 非常不合理

考虑优化 \(DP\)

仍然考虑 \((j,i]\) 段的长度,由于分的段数不会增大答案,当它的长度 \(\geqslant 2m\) 时,我们完全可以再给它切一刀,得到不劣的答案。通过此性质,可剪去大量无用转移。

此时再来考虑时间复杂度:\(O(tm)\) 还是不够优秀 只能达到70pts

再考虑优化 \(DP\)

假设正在求 \(f_i\),但在 \((i-m,i]\) 中没有任何点,这个 \(f_i\) 相对来说就是 “无用” 的。原因是若最后一段长度恰好 \(= m\),这里面又没有任何点,不分割也罢。长度 \(>m\) 时,完全可以把这一段的右边界往左“拖”,产生不劣的答案。

然而直接扔掉这个状态,会与上一个优化缩小转移范围起冲突,故无用的位置令 \(f_i = f_{i-m}\),防止漏解。

此时的时间复杂度就已经非常优秀了:\(O(nm^2+t)\) 稳定100pts

总结

这是一道非常好的区间类 \(DP\) 问题,值得反复思考

CPP

#include <bits/stdc++.h>
using namespace std;
const int N=4e6+10;
const int INF=1e9;
int n,m,T;
int a[N],f[N],s[N]; inline int max(int a,int b) {
return a>b?a:b;
} inline int min(int a,int b) {
return a<b?a:b;
} inline int read() {
int x, f = 1;
char c;
while (!((c = getchar()) >= '0' && c <= '9')) if (c == '-') f = -1;
x = c - '0';
while ((c = getchar()) >= '0' && c <= '9') (x *= 10) += c - '0';
return x * f;
} inline void write(int x) {
if (x < 0) putchar('-'), x = -x;
if (x > 9) write(x / 10);
putchar(x % 10 ^ 48);
} int main() {
n=read(),m=read();
for(int i=1; i<=n; i++) {
int t=read();
a[t]++;
s[t]+=t;
T=max(T,t);
}
for(int i=1; i<m+T; i++) {
a[i]+=a[i-1];
s[i]+=s[i-1];
}
for(int i=0; i<m+T; i++) {
if(i>=m && a[i-m]==a[i]) {
f[i]=f[i-m];
continue;
}
f[i]=a[i]*i-s[i];
for(int j=max(0,i-(m<<1)+1); j<=i-m; j++)
f[i]=min(f[i],f[j]+(a[i]-a[j])*i-(s[i]-s[j]));
}
int ans=INF;
for(int i=T; i<T+m; i++)
ans=min(ans,f[i]);
write(ans);
putchar('\n');
return 0;
}

P5017 [NOIP2018 普及组] 摆渡车的更多相关文章

  1. NOIP2018普及组复赛游记

    2018年11月10日,NOIP2018普及组复赛. 这是我初中阶段最后一次复赛了. 和往常一样,我们在预定的早上7点,没有出发. 10分钟之后,人终于到齐了,于是出发了,一路无话. 到了南航,合照三 ...

  2. NOIP2018普及组初赛解题报告

    本蒟蒻参加了今年的NOIP2018普及组的初赛 感觉要凉 总而言之,今年的题要说完全没有难度倒也不至于,还有不少拼RP的题,比如第一次问题求解考逻辑推理,第一次完善程序考双链表等 下面我就和大家一起看 ...

  3. P5018 [NOIP2018 普及组] 对称二叉树

    P5018 [NOIP2018 普及组] 对称二叉树 题目 P5018 思路 通过hash值来判断左右树是否相等 \(hl[i]\) 与 \(Hl[i]\) 是防止hash冲突, \(r\) 同理 注 ...

  4. NOIP2018普及组模拟赛

    向老师给的模拟赛,还没普及组难... 题目在洛谷团队里. 第一试三道水题,我46分钟就打完了,然后就AK了. 第二试一看,除了第二题要思考一段时间之外,还是比较水的,但是我得了Rank倒1,115分. ...

  5. NOIp2018普及组初赛试卷

    第二十四届全国青少年信息学奥林匹克联赛初赛(普及组C++语言试题)

  6. NOIp2018普及组T3暨洛谷P5017 摆渡车:题解

    题目链接:https://www.luogu.org/problemnew/show/P5017 emm,这次的真的不简单的,T3比T4难? 醉了... 蒟蒻肯定没有其他大佬讲的好啊,但肯定尽力,真的 ...

  7. Luogu 5017 NOIP2018普及组T3 摆渡车 (斜率优化 + 必要的转移进行剪枝)

    题意: 有 n 名同学要乘坐摆渡车从人大附中前往人民大学,第 i 位同学在第 ti​ 分钟去 等车.只有一辆摆渡车在工作,但摆渡车容量可以视为无限大.摆渡车从人大附中出发. 把车上的同学送到人民大学. ...

  8. [NOIP2018]普及组游记

    想不到自己还有机会写游记 ——sysky 考完一个月后 DAY -INF 报名 还为了拍照下载了一个PS 特地把自己P白了一点233 花里胡哨得提交了rg.noi.cn DAY -14~-2 停课集训 ...

  9. 『NOIP2018普及组题解』

    标题统计 题目描述 凯凯刚写了一篇美妙的作文,请问这篇作文的标题中有多少个字符? 注意:标题中可能包含大.小写英文字母.数字字符.空格和换行符.统计标题字 符数时,空格和换行符不计算在内. 输入格式 ...

随机推荐

  1. HDFS源码解析系列一——HDFS通信协议

    通信架构 首先,看下hdfs的交互图: 可以看到通信方面是有几个角色的:客户端(client).NameNode.SecondaryNamenode.DataNode;其中SecondaryNamen ...

  2. MySQL基本数据类型与约束条件

    昨日内容回顾 数据存储的演变 # 方向: 朝着更加统一和方便管理 数据库的发展史 # 由本地保存逐步演变为线上保存 数据库的本质 # 本质上就是一款CS架构的软件 """ ...

  3. c++ Message与Folder 拷贝 析构(没有动态空间的类)

    c++ Message与Folder 拷贝 析构(没有动态空间的类) 1.两个类里边分别保存一个对方的set表,当前类有拷贝或者销毁时需要更新另一个类的set表. 2.两个类都需要访问对方的priva ...

  4. Devops 开发运维高级篇之Jenkins+Docker+SpringCloud微服务持续集成(上)

    Devops 开发运维高级篇之Jenkins+Docker+SpringCloud微服务持续集成(上) Jenkins+Docker+SpringCloud持续集成流程说明 大致流程说明: 1) 开发 ...

  5. 为什么三层架构中业务层(service)、持久层(dao)需要使用一个接口?

    为什么三层架构中业务层(service).持久层(dao)需要使用一个接口? 如果没有接口那么我们在控制层使用业务层或业务层使用持久层时,必须要学习每个方法,若哪一天后者的方法名改变了则直接影响到前面 ...

  6. 超简单集成 HMS ML Kit 实现最大脸微笑抓拍

    前言 如果大家对 HMS ML Kit 人脸检测功能有所了解,相信已经动手调用我们提供的接口编写自己的 APP 啦.目前就有小伙伴在调用接口的过程中反馈,不太清楚 HMS ML Kit 文档中的 ML ...

  7. 【C# .Net GC】sos.dll 混合模式调试(托管调试+本机)

    当我们想使用本机调试器(如CDB或WinDBG)调试.NET应用程序时,我们必须在本机调试器和托管世界之间使用"桥",因为本机调试器本身并不理解托管代码.它是本机调试器.为了提供这 ...

  8. [iptables] 基于iptables实现的跨网络通信

    描述 在很多业务场景下,会遇上很多诡异的需求,不仅限于文章提及的需求,还有各种五花八门的需求,大部份的这些需求的产生都是来源于以前设计.规划上导致的问题.所以我们都会想尽办法为客户解决问题,维护好客户 ...

  9. 洛谷P3267.侦察守卫

    题目大意 一颗 \(n(1\leq n\leq 5\times 10^5)\) 个节点的树,在某一点 \(i\) 花费 \(w_{i}(w_{i}\leq 1000)\) 放置一个侦察守卫后可以监视到 ...

  10. Python:用正则表达式,提取字符串中的所有中文

    import re def clean(line): pattern = re.compile(u'[^\u4e00-\u9fa5]') #中文的范围为\u4e00-\u9fa5 line = re. ...