zoukankan      html  css  js  c++  java
  • [CF729C] Road to Cinema

    Description

    某人在起点处,到终点的距离为 (s)。汽车租赁公司提供 (n) 种车型,每种车型有属性 (c_i)(租车费用),(v_i)(油箱容量)。车子有两种前进方式:①慢速:(1km) 消耗 (1L) 汽油,花费 (2) 分钟。②快速:(1km) 消耗 (2L) 汽油,花费 (1) 分钟。路上有 (k) 个加油站,油都是免费的,加油不需要花费时间,且直接给油箱加满。问在 (t) 分钟内到达终点的最小花费是多少?若无法到达终点,输出 (-1)

    Solution

    考虑对于一段长为 (len) 的区间,设慢速 (x),快速 ((len-x)),则

    [t=2x+len-x=x+len \ v=x+2(len-x)=2len-x Rightarrow x=2len-v \ 0 le x le len ]

    如果直接求解得出的 (x > len) 则说明无法通行,如果直接求解的 (x <0),我们设其为 (0) 即可

    对所有的 (t) 求和,如果比给定的开始时间小,则可行

    这样我们就得到了一个 (O(nk)) 的算法

    考虑到费用本身并没有什么用,所以我们只需要二分出一个最小的,可以完成任务的 (v),然后对于所有 (v_i ge v) 对应的 (c_i) 取最小值即可

    #include <bits/stdc++.h>
    using namespace std;
    
    #define int long long
    const int N = 1000005;
    
    int s,t,n,c[N],v[N],k,g[N];
    
    signed main() {
        ios::sync_with_stdio(false);
        cin>>n>>k>>s>>t;
        for(int i=1;i<=n;i++) cin>>c[i]>>v[i];
        for(int i=1;i<=k;i++) cin>>g[i];
        sort(g+1,g+k+1);
        g[k+1]=s;
        int l=1,r=2e9;
        while(l<r) {
            int mid=(l+r)/2;
            int sum=0;
            int flag=1;
            for(int i=1;i<=k+1;i++) {
                int len=g[i]-g[i-1];
                int x=2*len-mid;
                if(x>len) {
                    flag=0;
                    break;
                }
                x=max(x,0ll);
                sum+=x+len;
            }
            if(sum>t) flag=0;
            if(flag) r=mid;
            else l=mid+1;
        }
        int ans=1e18;
        for(int i=1;i<=n;i++) if(v[i]>=r) ans=min(ans,c[i]);
        if(ans==1e18) cout<<-1;
        else cout<<ans;
    }
    
  • 相关阅读:
    小木虫等论坛自动签到程序发布
    第一篇随笔
    工作和兴趣哪个更重要?
    weblogic 启动时 报错
    C#动态调用webservice (转载)
    U盘加载,卸载,拔出,插入(转载)
    Simple zip archive unzipper(转载)
    Best C# Blogs(强烈推荐)
    数据无法导入ArcSDE
    Oracle10.2.0.1.0升级Oracle10.2.0.2.0补丁安装指南(转载)
  • 原文地址:https://www.cnblogs.com/mollnn/p/12811290.html
Copyright © 2011-2022 走看看