• 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)

     

     {   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 }
  • 相关阅读:
    5.7填数字游戏求解
    5.6判断回文数字
    5.5百钱买百鸡问题
    5.4三色球问题
    5.3哥德巴赫猜想的近似证明
    5.2求两个数的最大公约数和最小公倍数
    5.1舍罕王的失算
    4.19递归反向输出字符串
    Elasticsearch 安装
    linux 安装nginx步骤
  • 原文地址:https://www.cnblogs.com/thunder-110/p/9280009.html
Copyright © 2020-2023  润新知