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\) 座山 ...
随机推荐
- html 5中的新特性之强化表单元素及属性
之前我们判断用户提交的是否是Email 的时候,往往使用js 进行判断,但在html5中可以有新的方式进行判断而且更简单 <!DOCTYPE html> <html lang=&qu ...
- jQuery双向滑动杆 设置数值百分比
在线演示 本地下载
- Unix下 五种 I/O模型
Unix下共有五种I/O模型: 1. 阻塞式I/O 2. 非阻塞式I/O 3. I/O复用(select和poll) 4. 信号驱动式I/O(SIGIO) 5. 异步I/O(POSIX的aio ...
- Mybatis中接口和对应的mapper文件位置配置深入剖析
首先要说明的问题是,Mybatis中接口和对应的mapper文件不一定要放在同一个包下,放在一起的目的是为了Mybatis进行自动扫描,并且要注意此时java接口的名称和mapper文件的名称要相同, ...
- 数字组合问题:Combination,CombinationSum,CombinationSum2,CombinationSum3
Combination问题描述:给定n和k,找出1-n之间所有k个数的组合,例如:n=3,k=2,返回 [[1,2] [1,3] [2,3]] 算法分析:利用递归.递归边界就是curr.size( ...
- web.xml上监听器作用
<!--Spring ApplicationContext 载入 --> <listener> <listener-class>org.springframewor ...
- hdu 2126 Buy the souvenirs 二维01背包方案总数
Buy the souvenirs Time Limit: 10000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Other ...
- 机器学习三剑客之Pandas
pandas Pandas是基于Numpy开发出的,专门用于数据分析的开源Python库 Pandas的两大核心数据结构 Series(一维数据) Series 创建Series的方法 ...
- Kubernetes的网络模型
http://blog.csdn.net/zjysource/article/details/52052420
- Spring简洁版总结
一:为什么使用spring? spring泉眼,最好的水,在企业开发中,是业务层最好的框架 spring优点是什么? 1.低侵入,低耦合 2.方便集成其他框架 3.降低javaee开发难度 4.spr ...