Codeforces Round #422 C. Hacker, pack your bags! (二分)

来源:互联网 发布:百度云如何上传源码 编辑:程序博客网 时间:2024/06/16 07:20

题意

有 n 个旅行行程,每个指定 l r cost ,表示该行程的出发时间,结束时间,费用,旅行的持续时间记为 r-l+1

要求找到两个旅行行程,使得两者的持续时间和恰好为 x 。同时保证两个行程不会冲突,即需保证 ri<ljrj<li 。在能够找到的情况下,要求找到总费用最少的方案。

解题思路

将旅行行程按持续时间为第一关键字从小到大,结束时间为第二关键字从小到大排序。

统计前缀和为 同持续时间下,在结束时间 ri 前的行程的最小费用。

枚举每个行程 i 作为两个行程的后出发行程,每个 i 通过二分查找先出发行程 j 。在满足 v[i].duration + v[j].duration == xv[i].l > v[j].j 的情况下,记录最小的费用 minCost 。详细操作见函数 findMinTwins()

总体复杂度为 O(NlogN)

代码

import java.io.*;import java.util.*;/** * Created by Utop on 2017/7/3. */public class C {    static long INF = 1l<<60;    public static void main(String[] args) throws IOException {        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));        StringTokenizer st = new StringTokenizer(br.readLine());        int n = Integer.parseInt(st.nextToken());        int x = Integer.parseInt(st.nextToken());        Voucher[] v = new Voucher[n];        for (int i=0;i<n;i++) {            st = new StringTokenizer(br.readLine());            int l = Integer.parseInt(st.nextToken());            int r = Integer.parseInt(st.nextToken());            int cost = Integer.parseInt(st.nextToken());            v[i] = new Voucher(l, r, cost, r-l+1, cost);        }        Arrays.sort(v, new CMP());        for (int i=0;i<n;i++) {            if (i>0 && v[i].duration == v[i-1].duration) {                v[i].minCost = Math.min(v[i].minCost, v[i-1].minCost);            }        }        long ansCost = INF;        for (int i=0;i<n;i++) {            ansCost = Math.min(findMinTwins(v, i, 0, n-1, x), ansCost);        }        if (ansCost == INF) {            bw.write("-1");        } else {            bw.write(String.valueOf(ansCost));        }        bw.flush();        bw.close();    }    private static long findMinTwins(Voucher[] v, int rightPart, int l, int r, int x) {        int mid;        long ans = INF;        while (l <= r) {            mid = (l+r) >> 1;            if (v[rightPart].duration + v[mid].duration < x) {                l = mid + 1;            } else if (v[rightPart].duration + v[mid].duration == x) {                if (v[rightPart].l <= v[mid].r) {                    r = mid - 1;                } else {                    l = mid + 1;                    ans = Math.min(ans, v[rightPart].cost + v[mid].minCost);                }            } else {                r = mid - 1;            }        }        return ans;    }    static class Voucher extends ArrayList{        int l, r, cost, duration, minCost;        Voucher(int _l, int _r, int _cost, int _duration, int _minCost) {            this.l = _l;            this.r = _r;            this.cost = _cost;            this.duration = _duration;            this.minCost = _minCost;        }    }    static class CMP implements Comparator {        @Override        public int compare(Object o1, Object o2) {            Voucher v1 = (Voucher)o1;            Voucher v2 = (Voucher)o2;            if (v1.duration == v2.duration) {                if (v1.r == v2.r)   return 0;                return v1.r < v2.r ? -1 : 1;            }            return v1.duration < v2.duration ? -1 : 1;        }    }}
阅读全文
0 0
原创粉丝点击