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\) 座山 ...
随机推荐
- HTML5侧滑聊天面板
在线演示 本地下载
- APPIUM API整理(python)---其他辅助类
App运行类 1.current_activity current_activity(self): 用法: print(driver.current_activity()) Retrieves the ...
- 做Webservice时报错java.util.List是接口, 而 JAXB 无法处理接口。
Caused by: com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExc ...
- Batch Normalization 详解
一.背景意义 本篇博文主要讲解2015年深度学习领域,非常值得学习的一篇文献:<Batch Normalization: Accelerating Deep Network Training b ...
- SpringBoot 通用返回类设计
在项目中通常需要为前端设计通过的返回类,返回的格式为: { "status": "success", "data": {...} } 定义通 ...
- kafka入门使用
kafka版本0.11.0.1以上自带zookeeper,必须要求环境中有jdk,解压后进入目录 1.在kafka解压目录下下有一个config的文件夹,里面放置的是我们的配置文件 consumer. ...
- Sublime Text3 使用记录
Sublime Text 3 使用记录 来看下本文的大纲吧 介绍下,我的环境 操作系统:win10 64bit sublime Text 3 版本:3143 那么就开始啦. 一. ...
- SubSets,SubSets2, 求数组所有子集
问题描述: Given a set of distinct integers, nums, return all possible subsets. Note: The solution set mu ...
- Search a 2D Matrix,在有序矩阵查找,二分查找的变形; 行有序,列有序查找。
问题描述:矩阵每一行有序,每一行的最后一个元素小于下一行的第一个元素,查找. 算法分析:这样的矩阵其实就是一个有序序列,可以使用折半查找算法. public class SearchInSortedM ...
- 在数据库中添加数据以后,使用Mybatis进行查询结果为空
在数据库中添加数据以后,使用Mybatis进行查询结果为空,这是因为数据库中添加数据忘记commit的缘故.