CF311B Cats Transport
题意
Zxr960115 is owner of a large farm. He feeds m cute cats and employs p feeders. There's a straight road across the farm and n hills along the road, numbered from 1 to n from left to right. The distance between hill i and (i - 1) is di meters. The feeders live in hill 1.
One day, the cats went out to play. Cat i went on a trip to hill hi, finished its trip at time ti, and then waited at hill hi for a feeder. The feeders must take all the cats. Each feeder goes straightly from hill 1 to n without waiting at a hill and takes all the waiting cats at each hill away. Feeders walk at a speed of 1 meter per unit time and are strong enough to take as many cats as they want.
For example, suppose we have two hills (d2 = 1) and one cat that finished its trip at time 3 at hill 2 (h1 = 2). Then if the feeder leaves hill 1 at time 2 or at time 3, he can take this cat, but if he leaves hill 1 at time 1 he can't take it. If the feeder leaves hill 1 at time 2, the cat waits him for 0 time units, if the feeder leaves hill 1 at time 3, the cat waits him for 1 time units.
Your task is to schedule the time leaving from hill 1 for each feeder so that the sum of the waiting time of all cats is minimized.
\(2 ≤ n ≤ 10^5, 1 ≤ m ≤ 10^5, 1 ≤ p ≤ 100\)
分析
参照ww3113306的博客。
首先我们观察到山与距离其实是没有什么用的,因为对于任意一只猫,我们都可以直接算出如果有一个人要恰好接走它,需要在哪一时刻出发,我们设第i只猫对应的这个时刻为\(t_{i}\).
注意这个\(t_{i}\)是我自己新定义的,跟题目中的没有关系,下面所写的t都是我现在所定义的t,而跟原题面中的t没有任何关系。
然后我们对t数组排个序,于是题意转化为了有m只猫,每只猫有一个权值\(t_{i}\),如果出发时间大于等于\(t_{i}\) ,则可以接到第i只猫。设出发时间为x,则接到第i只猫时,这只猫会等待\(x - t_{i}\)的时间。现在有p个人,要求为每个人指定一个时间使得所有猫的等待时间之和最小。
然后我们继续转化题意。
观察到每个人相当于会选择一只猫i,然后选择在\(t_{i}\)时刻出发,恰好接走这只猫,顺便可以接走其他可以被接走的猫。
为什么是每个人都必须选一只猫呢?
观察到如果一个人出发,没有任何一只猫是恰好被接到的,所有猫都是等了一会再被接走的,那么这个人为什么不早出发一点,恰好接走一些猫呢?这样不仅可以接走和上一种方案相同的猫,还可以减小等待时间。
于是现在题意转化为了有m只猫,每只猫有一个权值\(t_{i}\)。如果第x个人选择了第i只猫,上一个出发的人选了第j只猫,则这个人可以接走[j + 1, i]中的所有猫,并且代价为\(\sum_{k = j + 1}^{i}{t_{i} - t_{k}}\)。现在有p个人,要求为每个人指定一只猫使得所有猫的等待时间之和最小。
先化一下式子:(其中s[i]表示\(\sum_{k = 1}^{i}{t[k]}\))
\[
\sum_{k = j + 1}^{i}{t_{i} - t_{k}} \\
= \sum_{k = j + 1}^{i}{t_{i}} - \sum_{k = j + 1}^{i}{t_{k}} \\
= (i - j) t_{i} - (s[i] - s[j])=(i−j)t
\]
于是我们设f[i][j]表示DP到第i个人,这个人选择了第j只猫的最小代价。
然后暴力枚举i,j,转移的时候再暴力枚举前一个人选了哪只猫即可。
但是这样的复杂度是\(pm^2\)的,观察到我们优化到\(pm\)就可以过了,又注意到式子中有一个跟i相关的量和一个跟j相关的量的乘积,我们考虑一下斜率优化。
我们先化一波式子。
\[
f[i][j] = f[i - 1][k] + (j - k) t_{j} - (s[j] - s[k])
\]
然后设\(x>y\),且\(x\)比\(y\)优,则
\[
\frac{f[i-1][x]+s[x]-f[i-1][y]-s[y]}{x-y}<t[i]
\]
小于单调增,下凸包+单调队列。
时间复杂度\(O(pm)\)
代码
我还是第一次做到多次斜率优化,并且弹出的和入队的比较内容不一样,感觉理解又深了一层。CF上面的题的质量很高,具有创新性,可以尝试。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<algorithm>
#include<bitset>
#include<cassert>
#include<ctime>
#include<cstring>
#define rg register
#define il inline
#define co const
template<class T>il T read()
{
rg T data=0;
rg int w=1;
rg char ch=getchar();
while(!isdigit(ch))
{
if(ch=='-')
w=-1;
ch=getchar();
}
while(isdigit(ch))
{
data=data*10+ch-'0';
ch=getchar();
}
return data*w;
}
template<class T>T read(T&x)
{
return x=read<T>();
}
using namespace std;
typedef long long ll;
co int M=1e5+1,P=101;
ll d[M],t[M],s[M];
ll f[P][M];
ll Up(int i,int x,int y) // edit 1: use ancient information,push anciently
{
return f[i-1][x]+s[x]-f[i-1][y]-s[y];
}
ll Down(int x,int y)
{
return x-y;
}
ll Cal(int i,int j,int k)
{
return f[i-1][k]+(j-k)*t[j]-s[j]+s[k];
}
int q[M];
int main()
{
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
int n=read<int>(),m=read<int>(),p=read<int>();
for(int i=2;i<=n;++i)
d[i]=d[i-1]+read<int>();
for(int i=1;i<=m;++i)
{
int h=read<int>();
t[i]=read<int>()-d[h];
}
sort(t+1,t+m+1);
for(int i=1;i<=m;++i)
s[i]=s[i-1]+t[i];
for(int j=1;j<=m;++j)
f[1][j]=j*t[j]-s[j];
for(int i=2;i<=p;++i)
{
int head=0,tail=0;
q[tail++]=0;
for(int j=1;j<=m;++j)
{
while(head+1<tail&&Up(i,q[head+1],q[head])<=t[j]*Down(q[head+1],q[head]))
++head;
f[i][j]=Cal(i,j,q[head]);
while(head+1<tail&&Up(i,j,q[tail-1])*Down(q[tail-1],q[tail-2])<=Up(i,q[tail-1],q[tail-2])*Down(j,q[tail-1]))
--tail;
q[tail++]=j; // edit 2:push j
}
}
printf("%I64d\n",f[p][m]);
return 0;
}
CF311B Cats Transport的更多相关文章
- CF311B Cats Transport 斜率优化DP
题面:CF311B Cats Transport 题解: 首先我们观察到山与距离其实是没有什么用的,因为对于任意一只猫,我们都可以直接算出如果有一个人要恰好接走它,需要在哪一时刻出发,我们设第i只猫对 ...
- 题解 CF311B Cats Transport
前置芝士:斜率优化 剥下这道题的外壳,让它变为一道裸的斜率优化. 很容易想到状态,但复杂度显然过不去,也没有单调性,只能自己创造. 令 $$c[i] = t - sum[i],sum[i] = \s ...
- CF311B Cats Transport(斜率优化)
题目描述 Zxr960115 是一个大农场主.他养了m只可爱的猫子,雇佣了p个铲屎官.这里有一条又直又长的道路穿过了农场,有n个山丘坐落在道路周围,编号自左往右从1到n.山丘i与山丘i-1的距离是Di ...
- $CF311B\ Cats\ Transport$ 斜率优化
AcWing Description Sol 设f[i][j]表示前i个饲养员接走前j只猫咪的最小等待时间. 要接到j猫咪,饲养员的最早出发时间是可求的,设为d: $ d[j]=Tj-\sum_{k= ...
- CF-311B Cats Transport(斜率优化DP)
题目链接 题目描述 小S是农场主,他养了 \(M\)只猫,雇了 \(P\) 位饲养员. 农场中有一条笔直的路,路边有 \(N\) 座山,从 \(1\) 到 \(N\)编号. 第 \(i\) 座山与第 ...
- 一本通1609【例 4】Cats Transport
1609:[例 4]Cats Transport 时间限制: 1000 ms 内存限制: 524288 KB sol:非常偷懒的截图了事 注意:只能猫等人,不能人等猫 对于每只猫,我们 ...
- Codeforces 311B Cats Transport 斜率优化dp
Cats Transport 出发时间居然能是负的,我服了... 卡了我十几次, 我一直以为斜率优化写搓了. 我们能得出dp方程式 dp[ i ][ j ] = min(dp[ k ][ j - 1 ...
- 【题解】Cats Transport (斜率优化+单调队列)
[题解]Cats Transport (斜率优化+单调队列) # When Who Problem Lang Verdict Time Memory 55331572 Jun/09/2019 19:1 ...
- Cats transport(codeforces311B)(斜率优化)
\(Cats Transport\) 感觉这道题题面不好讲,就自翻了一个新的,希望有助于大家理解其思路: 大致题意: \(wch\) 的家里有 \(N\) 座山(山呈直线分布,第 \(i-1\) 座山 ...
随机推荐
- Python3:数字类型和字符串类型的相互转换
Python3:数字类型和字符串类型的相互转换 一.python中字符串转换成数字 方法1: 类中进行导入:import string str='555'num=string.atoi(str)num ...
- MLP(多层神经网络)介绍
写在前面的 接触神经网络(ANN)的时间很长了,以前也只是学了学原理,做过一个BPN的练习,没有系统的总结过,最近看Torch的源码,对MLP有了更多的了解,写写自己学到的东西吧,算是做了一次总结! ...
- 如何自定义echarts 线性图的选择事件
最近在做公司的数据大盘,要用到图表显示,echarts研二的时候有用过,我就决定用它了. 这里用到一个可以同时显示多条曲线的line-charts,基本样子如下: 看到这个画红色圈圈的地方了吗??? ...
- [SCOI2005]扫雷Mine
1088: [SCOI2005]扫雷Mine Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 2028 Solved: 1187[Submit][St ...
- MySQL二进制日志文件过期天数设置说明
今天在处理业务库中二进制文件的时候,想更改二进制文件的过期天数,发现日期如果设置成2位以上的整数.都会出现如下的警告.不能成功的设置过期日期天数.MySQL版本从5.1到5.5都是一样的. mysql ...
- Jenkins自动打包配置
当时也是花费了不少时间来配置Jenkins自动打包的问题,觉得还是需要记录一下. 1.安装Jenkins,这个很简单,不需要多说. 2.下载Git Plugin,Gradle Plugin,Andro ...
- Mysql导出导入数据库
1. 导出数据库:mysqldump -u 用户名 -p 数据库名 > 导出的文件名 mysqldump -u root -p database > database.sql 2. 导入数 ...
- Java web应用中的常见字符编码问题的解决方法
以下是 Java Web应用的常见编码问题 1. html页面的编码 在web应用中,通常浏览器会根据http header: Content-type的值来决定用什么encoding, 比如遇到Co ...
- Elasticsearch6.4.3文档的映射
已经把ElasticSearch的核心概念和关系数据库做了一个对比,索引(index)相当于数据库,类型(type)相当于数据表,映射(Mapping)相当于数据表的表结构.ElasticSearch ...
- php数组元素去空,测试奇数偶数
<?php//返回奇数 function test_odd($var) { return($var & 1); } $a1=array("a","b&quo ...