T13 Delivery Club (CF875E)
T13 Delivery Club (CF875E)
这题就不是dp
CF传送门
洛谷传送门
题意简述
有两个快递员,分别在
由于快递员之间需要有对讲机联系,请你设计一种方案使得两个快递员之间的最长距离最短。
数据范围
题解
思路
看到这不禁想起了另一道题
有两个人(A和B)和n个任务,两个人完成每个任务的时间不同,但一个任务只需一个人完成。现在要求按顺序完成,两人可以同时完成不同的任务,求完成所有任务的最小时间。
两个人就比较难处理
于是不难想到多开一维,记录A的时间
设
答案即为
回到这道题,会发现一个比较难堪的事情:数据范围大多了!
这种做法根本行不通的 所以不要dp了
换个思路,不如先二分答案
这样问题就变为了判断两人最长距离是否能不超过
然后呢?正着来肯定要dfs了吧……
正着不行就反着来
送完第
现在我们关心另一个人的位置范围,假设就是
那
- 如果
a_{i-1} 正好就在l_i ~r_i 里
那
i-1 的情况肯定有一个人在a_{i-1} ,而另一个人的位置并没有限制(他在哪都能走到a_i )所以
l_{i-1}=a_i-k ,r_{i-1}=a_i+k
- 如果
a_{i-1} 不在l_i ~r_i 里呢?
那还是有一个人在
a_{i-1} 里,那另一个人又得在
a_{i-1}-k ~a_{i-1}+k 里,又得在l_i ~r_i 里l_{i-1}=max(a_{i-1}-k,l_i)$,$r_{i-1}=min(a_{i-1}+k,r_i)
- 要是这两部分根本就没有重叠部分呢?
那
l_{i-1}>r_{i-1} 了,return 即可(其实不return 也行,到最后也会return 掉)
最后会得到
我们只需要一个人在这个范围里就行了
因为另一个人只要跟他距离不超过
AC代码
#include<bits/stdc++.h>
using namespace std;
int n,s1,s2;
int a[100005];
bool check(int k){
int l=-1e9,r=1e9;
for(int i=n;i>=1;i--){
if(l<=a[i] && a[i]<=r) l=a[i]-k,r=a[i]+k;//a[i]在范围内
else l=max(l,a[i]-k),r=min(r,a[i]+k);//a[i]不在范围内
if(l>r) continue;
}
if((l<=s1 && s1<=r) || (l<=s2 && s2<=r)) return 1;//有一个在范围内
return 0;
}
int main(){
scanf("%d%d%d",&n,&s1,&s2);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
int l=abs(s1-s2),r=1e9;//注意l不能赋成1(或者在上面判断s1,s2的距离)
while(l!=r){
int mid=(l+r)>>1;
if(check(mid)) r=mid;
else l=mid+1;
}
printf("%d",l);
}