洛谷【1542】——包裹快递(二分)

传送门

开始以为是贪心,但发现行不通

如果每两个点之间贪时间极值,显然是行不通的,要尽量让每一段的速度平均

考虑到最终答案是最小满足条件的速度

发现答案具有单调性

对于每次的速度v,我们只需要判断其是否满足能在规定时间走到每一个地方就可以了

而且显然总是以速度v走具有答案包容性,总不会比以更小的速度走更差

因为若到某一个地方的时间早于可以签收的时间段,则必须在这个地方停留至可以签收

所以一个pre记录从上一个地方最早可以走的时间

注意要开long double ,否则精度会差一点

#include<bits/stdc++.h>
using namespace std;
#define eps 1e-4
int n;
double x[200005],y[200005],s[200005];
inline long double max(long double x,long double y){
 return (x-y>eps)?x:y;
}
inline bool check(long double k){
 long double pre=0;
 for(int i=1;i<=n;i++){
  pre+=s[i]/k;
  if(pre>y[i])return false;
  pre=max(pre,x[i]);
 }
 return true;
}
int main(){
 cin>>n;
 for(int i=1;i<=n;i++){
  scanf("%lf%lf%lf",&x[i],&y[i],&s[i]);
 }
 long double l=0,r=1e9;
 while(l+eps<r){
  long double mid=(l+r)/2;
  if(check(mid))r=mid;
  else l=mid;
 }
 double f=l;
 printf("%.2lf",f);
}

顺便求检查一下为什么这样写会炸第一个点

inline bool check(long double k){
 long double pre=0;
 for(int i=1;i<=n;i++){
  if(s[i]/(y[i]-pre)>k)return false;
  pre=max(pre+s[i]/k,x[i]);
 }
 return true;
}
原文地址:https://www.cnblogs.com/stargazer-cyk/p/10366420.html