题意:n个人,走一段l长的路,有一辆能装k个人的车,人的速度v1,车的速度v2,v1<v2。人只能上一次车。问走完这段路的最短时间。
思路:二分时间,通过推一些列公来判断是否可行。主要思想就是步行时间比当前枚举的时间多d,则每个人都要减少d时间的耗费,所以假设车载x米能使得k个人减少d的耗时。然后每个人都要上一次车,并且除最后一波人外,车方下人后都要返回。看看在走路的人到终点时,车能不能运着最后一波人到终点。
错误原因:
当二分上下界过小,ans又没赋初始值,那么可能不会给ans赋值就直接跳出了,所以尽量将二分的界限开的稍大一点,并且给ans赋值。二分精度不要太大,这道题1e-8就会超时。
ac代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<string>
#include<vector>
#include<unordered_map>
#define mod (1000000007)
using namespace std;
typedef long long ll;
const int maxn = 3e5 + 100;
const ll inf = 1e14;
const double eps=1e-7;//-8就T了,精度不要太大
int main() {
ll n,l,v1,v2,num,k;
cin>>n>>l>>v1>>v2>>k;
double T=l*1.0/v1;
double L=min(l*1.0/v2,0.25),R=T+10,ans;//ans赋初始值,或者将上下界调的宽一点,否则可能不能给ans赋值,直接跳出了
num=(n+k-1)/k;
while(R-L>eps){
double mid=(L+R)/2;
double dt=T-mid;
double x=(dt*v1*v2)/(v2-v1);
double t2=x/v2+(x-x*v1/v2)/(v1+v2);
double ok=x/v2+(l-x)/v1-(num-1)*(t2)-(x/v2);
if(ok>eps){
ans=mid;
R=mid;
}
else{
L=mid;
}
}
printf("%.6f\n",ans);
return 0 ;
}