【CodeForces - 701D】As Fast As Possible(二分)

题意: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 ;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章