Codeforces 822C Hacker, pack your bags! - 贪心

It‘s well known that the best way to distract from something is to do one‘s favourite thing. Job is such a thing for Leha.

So the hacker began to work hard in order to get rid of boredom. It means that Leha began to hack computers all over the world. For such zeal boss gave the hacker a vacation of exactly x days. You know the majority of people prefer to go somewhere for a vacation, so Leha immediately went to the travel agency. There he found out that n vouchers left. i-th voucher is characterized by three integers liri,costi — day of departure from Vi?kopolis, day of arriving back in Vi?kopolis and cost of the voucher correspondingly. The duration of thei-th voucher is a value ri - li + 1.

At the same time Leha wants to split his own vocation into two parts. Besides he wants to spend as little money as possible. Formally Leha wants to choose exactly two vouchers i and j (i ≠ j) so that they don‘t intersect, sum of their durations is exactly x and their total cost is as minimal as possible. Two vouchers i and j don‘t intersect if only at least one of the following conditions is fulfilled: ri < lj or rj < li.

Help Leha to choose the necessary vouchers!

Input

The first line contains two integers n and x (2 ≤ n, x ≤ 2·105) — the number of vouchers in the travel agency and the duration of Leha‘s vacation correspondingly.

Each of the next n lines contains three integers liri and costi (1 ≤ li ≤ ri ≤ 2·105, 1 ≤ costi ≤ 109) — description of the voucher.

Output

Print a single integer — a minimal amount of money that Leha will spend, or print  - 1 if it‘s impossible to choose two disjoint vouchers with the total duration exactly x.

Examples

input

4 51 3 41 2 55 6 11 2 4

output

5

input

3 24 6 32 4 13 5 4

output

-1

Note

In the first sample Leha should choose first and third vouchers. Hereupon the total duration will be equal to (3 - 1 + 1) + (6 - 5 + 1) = 5and the total cost will be 4 + 1 = 5.

In the second sample the duration of each voucher is 3 therefore it‘s impossible to choose two vouchers with the total duration equal to 2.



  题目大意 给定n个区间,每个区间有个费用,选择两个不相交(端点也不能重叠)的区间使得它们的长度总和恰好为x,并且使得它们的费用和最小。如果无解输出-1。

  根据常用套路,按照区间的长度进行分组。然后按照端点的大小(反正按左端点还是右端点都是一样的)进行排序。再拿两个数组跑一道前缀最小值和后缀最小值。

  现在枚举每一条旅行方案,在和它的长度之和恰好为x的另一个数组中,可以用lower_bound和upper_bound快速找出两侧合法的的最后一个和第一个,然后更新一下就好了(详细可以看代码)。

Code

  1 /**
  2  * Codeforces
  3  * Problem#822C
  4  * Accepted
  5  * Time:124ms
  6  * Memory:16416k
  7  */
  8 #include <iostream>
  9 #include <cstdio>
 10 #include <ctime>
 11 #include <cmath>
 12 #include <cctype>
 13 #include <cstring>
 14 #include <cstdlib>
 15 #include <fstream>
 16 #include <sstream>
 17 #include <algorithm>
 18 #include <map>
 19 #include <set>
 20 #include <stack>
 21 #include <queue>
 22 #include <vector>
 23 #include <stack>
 24 #ifndef WIN32
 25 #define Auto "%lld"
 26 #else
 27 #define Auto "%I64d"
 28 #endif
 29 using namespace std;
 30 typedef bool boolean;
 31 const signed int inf = (signed)((1u << 31) - 1);
 32 const double eps = 1e-6;
 33 const int binary_limit = 128;
 34 #define smin(a, b) a = min(a, b)
 35 #define smax(a, b) a = max(a, b)
 36 #define max3(a, b, c) max(a, max(b, c))
 37 #define min3(a, b, c) min(a, min(b, c))
 38 template<typename T>
 39 inline boolean readInteger(T& u){
 40     char x;
 41     int aFlag = 1;
 42     while(!isdigit((x = getchar())) && x != ‘-‘ && x != -1);
 43     if(x == -1) {
 44         ungetc(x, stdin);
 45         return false;
 46     }
 47     if(x == ‘-‘){
 48         x = getchar();
 49         aFlag = -1;
 50     }
 51     for(u = x - ‘0‘; isdigit((x = getchar())); u = (u << 1) + (u << 3) + x - ‘0‘);
 52     ungetc(x, stdin);
 53     u *= aFlag;
 54     return true;
 55 }
 56
 57 typedef class Trip {
 58     public:
 59         int l;
 60         int r;
 61         int fee;
 62
 63         Trip(int l = 0, int r = 0, int fee = 0):l(l), r(r), fee(fee) {        }
 64
 65         boolean operator < (Trip b) const {
 66             return l < b.l;
 67         }
 68 }Trip;
 69
 70 boolean operator < (const int& b, const Trip& a) {
 71     return b < a.l;
 72 }
 73
 74 int n, x;
 75 vector<Trip>* a;
 76 vector<int>* minu;        // in order
 77 vector<int>* mind;        // in opposite order
 78
 79 inline void init() {
 80     readInteger(n);
 81     readInteger(x);
 82     a = new vector<Trip>[x];
 83     minu = new vector<int>[x];
 84     mind = new vector<int>[x];
 85     for(int i = 1, l, r, c; i <= n; i++) {
 86         readInteger(l);
 87         readInteger(r);
 88         readInteger(c);
 89         int len = r - l + 1;
 90         if(len >= x)    continue;
 91         a[len].push_back(Trip(l, r, c));
 92     }
 93 }
 94
 95 int res = inf;
 96 inline void solve() {
 97     for(int i = 1; i < x; i++)
 98         if(!a[i].empty()) {
 99             sort(a[i].begin(), a[i].end());
100             minu[i].resize(a[i].size());
101             mind[i].resize(a[i].size());
102             for(int j = 0; j < (signed)a[i].size(); j++) {
103                 if(j == 0)    minu[i][j] = a[i][j].fee;
104                 else minu[i][j] = min(a[i][j].fee, minu[i][j - 1]);
105             }
106             for(int j = (signed)a[i].size() - 1; j >= 0; j--) {
107                 if(j == a[i].size() - 1)    mind[i][j] = a[i][j].fee;
108                 else mind[i][j] = min(a[i][j].fee, mind[i][j + 1]);
109             }
110         }
111
112     for(int i = 1; i < x; i++) {
113 //        cout << i << ":" << endl;
114         if(!a[i].empty()) {
115             for(int j = 0; j < a[i].size(); j++) {
116 //                cout << a[i][j].l << " " << a[i][j].r << endl;
117                 Trip &t = a[i][j];
118                 int len = t.r - t.l + 1;
119                 int ulen = x - len;
120                 int pos = upper_bound(a[ulen].begin(), a[ulen].end(), t.r) - a[ulen].begin();
121                 if(pos != a[ulen].size())    smin(res, t.fee + mind[ulen][pos]);
122                 pos = lower_bound(a[ulen].begin(), a[ulen].end(), t.l - ulen + 1) - a[ulen].begin() - 1;
123                 if(pos != -1)    smin(res, t.fee + minu[ulen][pos]);
124             }
125         }
126     }
127
128     if(res == inf)
129         puts("-1");
130     else
131         printf("%d\n", res);
132 }
133
134 int main() {
135     init();
136     solve();
137     return 0;
138 }
时间: 2024-07-31 10:41:04

Codeforces 822C Hacker, pack your bags! - 贪心的相关文章

CodeForces 822C Hacker, pack your bags!

题意 给出一些闭区间(始末+代价),选取两段不重合区间使长度之和恰为x且代价最低 思路 相同持续时间的放在一个vector中,内部再对起始时间排序,从后向前扫获取对应起始时间的最优代价,存在minn中,对时间 i 从前向后扫,在对应的k-i中二分找第一个不重合的区间,其对应的minn加上 i 的cost即为出发时间为 i 时的最优解 代码 #include<bits/stdc++.h> using namespace std; int n, k; struct EVE{ int st,ed,v

Codeforces Round #422 (Div. 2) C. Hacker, pack your bags! 排序,贪心

C. Hacker, pack your bags! It's well known that the best way to distract from something is to do one's favourite thing. Job is such a thing for Leha. So the hacker began to work hard in order to get rid of boredom. It means that Leha began to hack co

Codeforces Round #422 (Div. 2) C. Hacker, pack your bags! 排序+贪心

链接: http://codeforces.com/contest/822/problem/C 题意: 有x天的假期, 有n张旅行票, 每张票有起始时间l, 结束时间r, 花费cost, 想把假期分成两部分出去旅游, 两部分时间不能重合(ri < lj || rj < li), 问最小花费是多少, 如果不能两部分, 输出-1 题解: CF官方解法, 效率O(nlogn2) 设置一个结构体, struct P{int p, len, cost, type}; 将每张票(l, r, cost) 表

Codeforces Round #422 (Div. 2) C Hacker, pack your bags!

It's well known that the best way to distract from something is to do one's favourite thing. Job is such a thing for Leha. So the hacker began to work hard in order to get rid of boredom. It means that Leha began to hack computers all over the world.

#422(div2)C. Hacker, pack your bags!

题意:给出n个区间和X,每个区间有左右边界和价值,li,ri,x.然后问从这n个区间找出2个不重合的区间,他们的区间长度和为x,并且价值最小 思路:我们可以预处理出每个长度所包含的区间,然后可以保存每个区间L的位置,和R的位置,那么在某个位置(某个L),前面的都是无重合,在判断下X-当前区间的长度 1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long LL; 4 const long long INF=1e18

Codeforces 583 DIV2 Robot&#39;s Task 贪心

原题链接:http://codeforces.com/problemset/problem/583/B 题意: 就..要打开一个电脑,必须至少先打开其他若干电脑,每次转向有个花费,让你设计一个序列,使得总花费最小. 题解: 就傻傻的走就好..从左走到右,再走回来,更新序列和答案就好. 代码: #include<iostream> #include<cstring> #include<algorithm> #include<cstdio> #define MA

Codeforces 442C Artem and Array(stack+贪心)

题目连接:Codeforces 442C Artem and Array 题目大意:给出一个数组,每次删除一个数,删除一个数的得分为两边数的最小值,如果左右有一边不存在则算作0分.问最大得分是多少. 解题思路:首先将连续的a,b,c,a > b && c > b的情况将c掉,获得min(a,b)分,这样处理后数组变成一个递増再递减的序列,除了最大和第二大的取不到,其他数字均可以得分. 样例:4 10 2 2 8 #include <cstdio> #include

Codeforces 18D Seller Bob java大数+贪心

题目链接:点击打开链接 java: import java.math.BigInteger; import java.util.Scanner; public class Main { static int N = 5005; static BigInteger[] er = new BigInteger[N]; static BigInteger E = new BigInteger("2"); static int[] a = new int[N]; static int[] ma

Codeforces 437C The Child and Toy(贪心)

题目连接:Codeforces 437C The Child and Toy 题目大意:孩子有一个玩具,有n个部件组成,m条绳子组成,每条绳子连接两个部件.小孩比较顽皮,要将玩具拆成不可分割的部件,每次剪断一条绳子的代价是该绳子连接的两个部件的权值中较小的值.问说最小的总代价是多少. 解题思路:以为每条边都是要被剪断的,所以将节点按照代价值从大到小排序,每次拿掉权值大的点,与该点连接并且还未剪断的边均用另外点的权值. #include <cstdio> #include <cstring