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 li, ri,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!
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 li, ri and costi (1 ≤ li ≤ ri ≤ 2·105, 1 ≤ costi ≤ 109) — description of the voucher.
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.
4 5
1 3 4
1 2 5
5 6 1
1 2 4
5
3 2
4 6 3
2 4 1
3 5 4
-1
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
/**
* Codeforces
* Problem#822C
* Accepted
* Time:124ms
* Memory:16416k
*/
#include <iostream>
#include <cstdio>
#include <ctime>
#include <cmath>
#include <cctype>
#include <cstring>
#include <cstdlib>
#include <fstream>
#include <sstream>
#include <algorithm>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <vector>
#include <stack>
#ifndef WIN32
#define Auto "%lld"
#else
#define Auto "%I64d"
#endif
using namespace std;
typedef bool boolean;
const signed int inf = (signed)((1u << ) - );
const double eps = 1e-;
const int binary_limit = ;
#define smin(a, b) a = min(a, b)
#define smax(a, b) a = max(a, b)
#define max3(a, b, c) max(a, max(b, c))
#define min3(a, b, c) min(a, min(b, c))
template<typename T>
inline boolean readInteger(T& u){
char x;
int aFlag = ;
while(!isdigit((x = getchar())) && x != '-' && x != -);
if(x == -) {
ungetc(x, stdin);
return false;
}
if(x == '-'){
x = getchar();
aFlag = -;
}
for(u = x - ''; isdigit((x = getchar())); u = (u << ) + (u << ) + x - '');
ungetc(x, stdin);
u *= aFlag;
return true;
} typedef class Trip {
public:
int l;
int r;
int fee; Trip(int l = , int r = , int fee = ):l(l), r(r), fee(fee) { } boolean operator < (Trip b) const {
return l < b.l;
}
}Trip; boolean operator < (const int& b, const Trip& a) {
return b < a.l;
} int n, x;
vector<Trip>* a;
vector<int>* minu; // in order
vector<int>* mind; // in opposite order inline void init() {
readInteger(n);
readInteger(x);
a = new vector<Trip>[x];
minu = new vector<int>[x];
mind = new vector<int>[x];
for(int i = , l, r, c; i <= n; i++) {
readInteger(l);
readInteger(r);
readInteger(c);
int len = r - l + ;
if(len >= x) continue;
a[len].push_back(Trip(l, r, c));
}
} int res = inf;
inline void solve() {
for(int i = ; i < x; i++)
if(!a[i].empty()) {
sort(a[i].begin(), a[i].end());
minu[i].resize(a[i].size());
mind[i].resize(a[i].size());
for(int j = ; j < (signed)a[i].size(); j++) {
if(j == ) minu[i][j] = a[i][j].fee;
else minu[i][j] = min(a[i][j].fee, minu[i][j - ]);
}
for(int j = (signed)a[i].size() - ; j >= ; j--) {
if(j == a[i].size() - ) mind[i][j] = a[i][j].fee;
else mind[i][j] = min(a[i][j].fee, mind[i][j + ]);
}
} for(int i = ; i < x; i++) {
// cout << i << ":" << endl;
if(!a[i].empty()) {
for(int j = ; j < a[i].size(); j++) {
// cout << a[i][j].l << " " << a[i][j].r << endl;
Trip &t = a[i][j];
int len = t.r - t.l + ;
int ulen = x - len;
int pos = upper_bound(a[ulen].begin(), a[ulen].end(), t.r) - a[ulen].begin();
if(pos != a[ulen].size()) smin(res, t.fee + mind[ulen][pos]);
pos = lower_bound(a[ulen].begin(), a[ulen].end(), t.l - ulen + ) - a[ulen].begin() - ;
if(pos != -) smin(res, t.fee + minu[ulen][pos]);
}
}
} if(res == inf)
puts("-1");
else
printf("%d\n", res);
} int main() {
init();
solve();
return ;
}
Codeforces 822C Hacker, pack your bags! - 贪心的更多相关文章
- CodeForces 754D Fedor and coupons&&CodeForces 822C Hacker, pack your bags!
D. Fedor and coupons time limit per test 4 seconds memory limit per test 256 megabytes input standar ...
- Codeforces 822C Hacker, pack your bags!(思维)
题目大意:给你n个旅券,上面有开始时间l,结束时间r,和花费cost,要求选择两张时间不相交的旅券时间长度相加为x,且要求花费最少. 解题思路:看了大佬的才会写!其实和之前Codeforces 776 ...
- CodeForces 822C Hacker, pack your bags!
题意 给出一些闭区间(始末+代价),选取两段不重合区间使长度之和恰为x且代价最低 思路 相同持续时间的放在一个vector中,内部再对起始时间排序,从后向前扫获取对应起始时间的最优代价,存在minn中 ...
- Codefroces 822C Hacker, pack your bags!
C. Hacker, pack your bags! time limit per test 2 seconds memory limit per test 256 megabytes input s ...
- 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 ...
- CF822C Hacker, pack your bags!(思维)
Hacker, pack your bags [题目链接]Hacker, pack your bags &题意: 有n条线段(n<=2e5) 每条线段有左端点li,右端点ri,价值cos ...
- Codeforces822 C. Hacker, pack your bags!
C. Hacker, pack your bags! time limit per test 2 seconds memory limit per test 256 megabytes input s ...
- 【Codeforces Round #422 (Div. 2) C】Hacker, pack your bags!(二分写法)
[题目链接]:http://codeforces.com/contest/822/problem/C [题意] 有n个旅行计划, 每个旅行计划以开始日期li,结束日期ri,以及花费金钱costi描述; ...
- codeforces 822 C. Hacker, pack your bags!(思维+dp)
题目链接:http://codeforces.com/contest/822/submission/28248100 题解:多维的可以先降一下维度sort一下可以而且这种区间类型的可以拆一下区间只要加 ...
随机推荐
- 多表关联查询_resultMap_集合对象
多表关联查询_resultMap_集合对象_N+1方式实现 package com.bjsxt.mapper; import java.util.List; import com.bjsxt.pojo ...
- php实现记住密码下次自动登陆
这篇博客里面还写到 实现“记住我的登录状态”的功能方法,简言之,就是对首先对session进行用户信息赋值,检测session,失效后,利用cookie对其赋值: 在实现过程中,根据网上一些代码贴,整 ...
- 在webpack自定义配置antd的按需加载和修改主题色
最近使用antd来做react项目的UI.从antd官网上,在使用create-react-app脚手架搭建项目时步骤如下: (1)添加模块 react-app-rewired, babel-plug ...
- LeetCode71.简化路径
给定一个文档 (Unix-style) 的完全路径,请进行路径简化. 例如,path = "/home/", => "/home"path = " ...
- 环形数组 最大子段和 dp
题目链接:https://nanti.jisuanke.com/t/36118 环形数组的连续最大子段和,有两种情况. 1.最大和的这个子段没有包含头尾.所以直接dp[i] = max(dp[i-1] ...
- c++引用和指针的彻底理解
★ 相同点: 1. 都是地址的概念: 指针指向一块内存,它的内容是所指内存的地址:引用是某块内存的别名. ★ 区别: 1. 指针是一个实体,而引用仅是个别名: 2. 引用使用时无需解引用(*),指 ...
- html5-字体css
#div1{font-size: 50px;}#div2{font-size: 50%;}#div3{font-size: 300%}#div4{font-size: 3em;}#div5{font- ...
- RabbitMQ CentOS6.5 安装
1.安装前准备工作 1)安装RbbitMQ之前先安装ErLang 2)安装ErLang之前需要安装最新的socat 3)安装方式有多种,可以下包安装,可以直接下载rpm文件安装,推荐前者. 4)安装的 ...
- session_start 统计实时访客人数
void Session_Start(object sender, EventArgs e) { Application.Lock(); Application["OnLine"] ...
- 【Linux学习九】负载均衡
环境 虚拟机:VMware 10 Linux版本:CentOS-6.5-x86_64 客户端:Xshell4 FTP:Xftp4 一.高并发 随着应用访问量的增加,带来高并发处理问题. 具体有两个: ...