Road to Cinema(贪心+二分)

https://www.cnblogs.com/flipped/p/6083973.html       原博客转载

http://codeforces.com/group/1EzrFFyOc0/contest/738/problem/C     题目链接

题意:n个价格c[i],油量v[i]的汽车,求最便宜的一辆使得能在t时间内到达s,路途中有k个位置在g[i]的加油站,可以免费加满油,且不耗时间。每辆车有两种运行模式可以随时切换:1.每米一分钟两升油;2.每米两分钟一升油。

题解:二分求可以到达s的最小油量。对于油量v,能到达s的条件是:油量足够经过最长路程(中途不能加油);总的最小时间不超过t。为了求最小时间,可以用线性规划:一段不加油的路程长度为l,假设x米运行的是1.模式,则l-x米运行的是2.模式。总时间为t。则有

   t=x+2(lx)

  vx2+lx

  x0lx0(1)

 

扫描二维码关注公众号,回复: 1947177 查看本文章

 {   t=x+2∗(l−x)

  v≥x∗2+l−x

  x≥0

  l−x≥0

 

化简一下:

   t=2lx

  xvl

  lx0(2)

 

  {t=2∗l−x

  x≤v−l

  l≥x≥0

 

最后得到:

  tmin=2lxmax
  =2lmin(vl,l)
  =max(l3v,l)tmin
  =2∗l−xmax
  =2∗l−min(v−l,l)
  =max( l∗3−v,l )

且v≥l,可以改为v≥max(l)。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<cmath>
 6 #include<set>
 7 #include<vector>
 8 #include<stack>
 9 #include<queue>
10 #include<map>
11 using namespace std;
12 #define ll long long
13 #define se second
14 #define fi first
15 const int Mos = 0x7FFFFFFF;  //2147483647
16 const int nMos = 0x80000000;  //-2147483648
17 const int N=2e5+5;
18 
19 int n,k,s,t,dis;
20 int c[N],v[N],g[N];
21 
22 bool check(int vv) //油量
23 {
24     if(vv<dis) return 0; //如果开低速的油都不够
25     int sumt=0;
26     for(int i=1;i<=k+1;i++)
27     {
28         sumt+= max(g[i],3*g[i]-vv);
29         if(sumt>t) return 0;  //超出时间
30     }
31     return 1;
32 }
33 int main()
34 {
35     cin>>n>>k>>s>>t;
36     for(int i=1;i<=n;i++) scanf("%d%d",&c[i],&v[i]);
37     for(int i=1;i<=k;i++) scanf("%d",&g[i]);
38     g[k+1]=s;
39     sort(g+1,g+1+k);
40     for(int i=k+1;i>=1;i--)
41         dis=max(dis,g[i]-=g[i-1]);  //找出加油站间最长间隔,顺便把g[i]变为距离前面一个的距离
42     int l=0,r=1e9+5,mid,res=0;
43     while(l<=r)  //二分找出最少需要的油量;
44     {
45         mid=(l+r)>>1;
46         if( check(mid) )   r=mid-1,res=mid; //记录最优的res
47         else    l=mid+1;
48     }
49     int ans=1e9+1;
50     if(res)
51         for(int i=1;i<=n;i++)
52             if(v[i]>=res) ans=min(ans,c[i]);
53     if(ans>=1e9+1) ans=-1;
54 
55     cout<<ans<<endl;
56 }

猜你喜欢

转载自www.cnblogs.com/thunder-110/p/9280009.html