『摆渡车 斜率优化dp及总结』
<更新提示>
<第一次更新>摆渡车的题解我已经写过一遍了,在这里,这次主要从斜率优化的角度讲一下摆渡车,并总结一下斜率优化会出现的一些奇奇怪怪的错误。
<正文>
摆渡车
Description
有 n 名同学要乘坐摆渡车从人大附中前往人民大学,第 i 位同学在第 titi分钟去 等车。只有一辆摆渡车在工作,但摆渡车容量可以视为无限大。摆渡车从人大附中出发、 把车上的同学送到人民大学、再回到人大附中(去接其他同学),这样往返一趟总共花费m分钟(同学上下车时间忽略不计)。摆渡车要将所有同学都送到人民大学。
凯凯很好奇,如果他能任意安排摆渡车出发的时间,那么这些同学的等车时间之和最小为多少呢?
注意:摆渡车回到人大附中后可以即刻出发。
Input Format
第一行包含两个正整数 n,m,以一个空格分开,分别代表等车人数和摆渡车往返 一趟的时间。
第二行包含 n 个正整数,相邻两数之间以一个空格分隔,第 i 个非负整数 ti代 表第 i 个同学到达车站的时刻。
Output Format
输出一行,一个整数,表示所有同学等车时间之和的最小值(单位:分钟)。
Sample Input
5 5
11 13 1 5 5
Sample Output
4
解析
如果考虑斜率优化的思路的话,我们可以这样设置状态:\(f_i\)代表到了时间点\(i\),所有同学等待时间的最小和。那么就可以这样写状态转移方程:
\]
然后可以用前缀和把求和式拆一下,设\(cnt_i\)代表到时间点\(i\)位置已经到达过车站的学生个数,\(sum_i\)代表已经到达过车站的学生的到达时间总和,则原方程可以写为:
\]
好了,看到有\(i,j\)乘积项就可以考虑斜率优化了,我们再整理一下式子:
\]
假设找到了最优的决策点\(j\),那么就有:
\]
把\(f_j+sum_j\)看做\(y\),把\(cnt_j\)看做\(x\),把\(i\)看作\(k\),把\(f_i-cnt_i*i+sum_i\)看做\(b\),这就是直线方程了,然后直接维护下凸壳,利用决策单调性转移就可以了。
但其实这道题还没那么简单,其实还有如下几个问题:
\(1.\) 变量\(j\)有取值范围,需满足\(j\leq i-m\)。
\(2.\) 计算斜率可能出现分母为\(0\)。
\(3.\) \(f\)数组缺少部分初值。
对于第一个问题,我们采用分层推入队列的方法:在维护单调队列时,每当完成了对\(f_i\)的转移,我们应尝试把\(i-m+1\)这一个决策点推入队列,这样就能保证满足决策变量\(j\)的取值范围合法,其他题也是一样的。
对于第二个问题,计算斜率时分母为\(0\)就对应了坐标系内两个点坐标横坐标相同,但是纵坐标不同的情况。相应地,我们将这种情况视为两点之间的斜率为\(+\infty\)或\(-\infty\)(按照两点位置判断)处理即可,这样处理既简单,又对正确性没有影响。
第三个问题就对应了第一个问题,对于前\(m\)的点,显然我们是没有初值的,也无法用单调队列转移,所以我们必须要暴力对前\(m\)个状态进行更新,才能进行斜率优化,这个就根据\(dp\)式来更新就可以了。
\(Code:\)
#include <bits/stdc++.h>
using namespace std;
const long long N=1e6+20,M=1e6+20,T=9e6+20,INF=1e18;
long long n,m,maxT,c[T],s[T],f[T];
long long q[T],head,tail,ans=INF;
inline void input(void)
{
scanf("%lld%lld",&n,&m);
for (int i=1;i<=n;i++)
{
long long t;scanf("%lld",&t);
maxT = max(t,maxT);
s[t] += t; c[t] ++;
}
}
inline void init(void)
{
for (int i=1;i<=maxT+m;i++)
c[i] += c[i-1] , s[i] += s[i-1];
}
inline double slope(int x,int y)
{
if ( c[x] == c[y] ) return f[y]+s[y] > f[x]+s[x] ? INF * 1.0 : INF * -1.0;
return ( 1.0 * (f[y]+s[y]) - 1.0 * (f[x]+s[x]) ) / ( 1.0 * (c[y]) - 1.0 * (c[x]) );
}
//f[i] = min{f[j]+(c[i]-c[j])*i-(s[i]-s[j])}
inline void dp(void)
{
head = tail = 1; q[tail] = 0;
for (int i=1;i<m;i++)
f[i] = c[i] * i - s[i];
for (int i=m;i<=maxT+m;i++)
{
while ( head<tail && slope(q[head],q[head+1]) <= 1.0 * i ) head++;
f[i] = f[q[head]] + (c[i]-c[q[head]]) * i - (s[i]-s[q[head]]);
while ( head<tail && slope(q[tail-1],q[tail]) >= slope(q[tail],i-m+1) ) tail--;
q[++tail] = i-m+1;
if (i>=maxT) ans = min(ans,f[i]);
}
}
int main(void)
{
input();
init();
dp();
printf("%lld\n",ans);
return 0;
}
总结
其实本题中的这一些问题就对应了斜率优化题中可能会出现的种种问题,以下我们对斜率优化总结一下:
解题基本思路:
\(1.\) 写出状态转移方程,看看能不能用斜率优化
\(2.\) 如果可以斜率优化,将方程改写为直线方程的形式,先用数形结合法尝试做一下
\(3.\) 如果可行,尝试证明一下决策单调性,用代数法推一推
\(4.\) 看看是什么类型的斜率优化:取\(min\)就维护下凸壳,取\(max\)就维护上凸壳
\(5.\) 注意一下\(i,j\)乘积项的符号,如果是负数一般把负号看成是与\(j\)有关项的而非斜率项的,然后在坐标系内重新画一下图,看看维护的到底是什么
\(6.\)最后看单调性会不会出问题,如果决策单调性出问题就用二分答案,如果凸壳不能单调维护就用\(cdq\)分治
常见问题:
\(1.\) 决策变量有取值范围,在推入队列的时候改为推入可取的决策变量
\(2.\) \(dp\)数组有部分初值无法用斜率优化转移得到(决策变量被取值范围限制),暴力先转移初值
\(3.\) 斜率会出现整数被\(0\)除,特判返回\(+\infty\)或\(-\infty\)
\(4.\) 计算斜率可能会出锅,\(slope\)函数尽量公式化:数值大的下标为\(y\),数值小的下标为\(x\),计算时用\(val(y)-val(x)\)
\(5.\) 单调队列要注意:必须在队列内有至少两个元素才能删除队首或队尾
\(6.\) 浮点数运算很容易出问题,计算斜率或比较大小时记得转为\(double\)类型
\(7.\) 精度可能会出问题,适当时计算斜率的除法要转为乘法
\(8.\) 考虑单调队列内是否要存一个转移初值(如\(0\))
\(9.\) \(dp\)数组的初值:\(+\infty\)或\(-\infty\)或\(0\),是否要\(long\ long\),无穷要开够大
\(10.\) 弹出队首不优元素和队尾不在下凸壳内元素比较斜率时,请将等号加上(\(<\)尽量写成\(\leq\),\(>\)尽量写成\(\geq\))
\(11.\) 写二分,请按模板来:\(while\)循环写\(l<r\),每一次计算\(slope(q[mid],q[mid+1])\),若小于等于斜率关键值,则\(l=mid+1\),反之\(r=mid\),最后返回\(q[l]\)
\(12.\)写\(cdq\)分治,也请按模板来:记得在递归子问题前先左右按编号大小分一下,避免出现\(f_i\)转移到\(f_j\)但是\(j>i\)的情况
\(cdq\)分治和二分的模板见『任务安排 斜率优化及其变形』,另外一片斜率优化数形结合入门博客见『玩具装箱TOY 斜率优化DP』,简单总结博客见『土地征用 Land Acquisition 斜率优化DP』。
<后记>
『摆渡车 斜率优化dp及总结』的更多相关文章
- 『土地征用 Land Acquisition 斜率优化DP』
斜率优化DP的综合运用,对斜率优化的新理解. 详细介绍见『玩具装箱TOY 斜率优化DP』 土地征用 Land Acquisition(USACO08MAR) Description Farmer Jo ...
- 【学习笔记】动态规划—斜率优化DP(超详细)
[学习笔记]动态规划-斜率优化DP(超详细) [前言] 第一次写这么长的文章. 写完后感觉对斜优的理解又加深了一些. 斜优通常与决策单调性同时出现.可以说决策单调性是斜率优化的前提. 斜率优化 \(D ...
- bzoj-4518 4518: [Sdoi2016]征途(斜率优化dp)
题目链接: 4518: [Sdoi2016]征途 Description Pine开始了从S地到T地的征途. 从S地到T地的路可以划分成n段,相邻两段路的分界点设有休息站. Pine计划用m天到达T地 ...
- bzoj-1096 1096: [ZJOI2007]仓库建设(斜率优化dp)
题目链接: 1096: [ZJOI2007]仓库建设 Description L公司有N个工厂,由高到底分布在一座山上.如图所示,工厂1在山顶,工厂N在山脚.由于这座山处于高原内陆地区(干燥少雨),L ...
- [BZOJ3156]防御准备(斜率优化DP)
题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3156 分析: 简单的斜率优化DP
- 【BZOJ-1096】仓库建设 斜率优化DP
1096: [ZJOI2007]仓库建设 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 3719 Solved: 1633[Submit][Stat ...
- BZOJ 1010: [HNOI2008]玩具装箱toy 斜率优化DP
1010: [HNOI2008]玩具装箱toy Description P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再 ...
- BZOJ 3156: 防御准备 斜率优化DP
3156: 防御准备 Description Input 第一行为一个整数N表示战线的总长度. 第二行N个整数,第i个整数表示在位置i放置守卫塔的花费Ai. Output 共一个整数,表示最小的战 ...
- HDU2829 Lawrence(斜率优化dp)
学了模板题之后上网搜下斜率优化dp的题目,然后就看到这道题,知道是斜率dp之后有思路就可以自己做不出来,要是不事先知道的话那就说不定了. 题意:给你n个数,一开始n个数相邻的数之间是被东西连着的,对于 ...
随机推荐
- Vue axios异步获取后台数据alert提示undefined
记录一个小问题,关于分页查询套餐 前台通过axios异步请求获取后台数据alert弹出数据提示undefined 下面有三个bean PageResult /** * 分页结果封装对象 */ publ ...
- linux socket编程系统调用栈
目录 一.网络协议参考模型简介 二.SOCKET概述 三.SOCKET基本数据结构 1.TCP通信编程 2.服务器端实例代码 3.客户端实例代码 4.头文件socketwrapper.h 5.程序实现 ...
- LOJ 3156: 「NOI2019」回家路线
题目传送门:LOJ #3156. 题意简述: 有一张 \(n\) 个点 \(m\) 条边的有向图,边有两个权值 \(p_i\) 和 \(q_i\)(\(p_i<q_i\))表示若 \(p_i\) ...
- centos7下搭建JDK和Hadoop
涉及基础操作命令 这里只是将涉及到的提了下一下具体的使用还需要读者自己查阅资料 tar 解压命令 su 进入root用户模式 rm -rf 删除 cd /文件名/.../ 进入某个文件夹下 注意要逐层 ...
- 从0到1的开发,社交App 完成
内容概要 GitHub链接:GitHub链接 客户端使用Android Studio 服务端使用IDEA + SpringBoot + MyBaits 完成功能 添加好友,即时聊天,社交广场 只是一个 ...
- jvm堆、栈、String常量池
原文地址:http://blog.csdn.net/tophawk/article/details/78704074 程序计数器:它的生命周期与线程相同,线程私有.较小的内存区域,用以完成分支.循环. ...
- Pandas | 19 合并/连接
Pandas具有功能全面的高性能内存中连接操作,与SQL等关系数据库非常相似.Pandas提供了一个单独的merge()函数,作为DataFrame对象之间所有标准数据库连接操作的入口 - pd.me ...
- ESA2GJK1DH1K升级篇: IAP详解
前言: 源码下载链接: https://gitee.com/yang456/STM32_IAP_Learn.git 后期所有出售的升级程序皆在此代码之上进行优化和开发 请必须把此文章各个的地方的说明看 ...
- 请写出css中选择器(元素选择器、类选择器、id选择器)的优先级顺序,和当各种选择器组合时,优先级的计算规则是什么?
id选择器>类选择器>元素选择器 规则:选择器的权重值表述为4个部分,用0,0,0,0表示. 通配符*的权重为0,0,0,0 标签选择器.伪元素选择器的权重为0,0,0,1 类选择器.属性 ...
- 【CSP-S膜你考】我们的可可西里
我们的可可西里 题面 转眼到了2008年的6月9日,盼望已久的高考结束了.我们踏上了向西的旅程(本来是想写西去之路,可是考虑不太妥当).可可西里,多么诱人的名词,充满了奇幻的色彩和自然的淳朴.从可可西 ...