Codeforces Round #422 (Div. 2) C. Hacker, pack your bags! 排序, 贪心, 暴力(居然可以n方暴力)
来源:互联网 发布:路由器怎么没有网络啊 编辑:程序博客网 时间:2024/06/05 03:30
题目链接: Hacker, pack your bags!
题目大意
有x天的假期, 有n张旅行票, 每张票有起始时间l, 结束时间r, 花费cost, 想把假期分成两部分出去旅游, 两部分时间不能重合(ri < lj || rj < li), 问最小花费是多少, 如果不能两部分, 输出-1
思路
1. 排序, 贪心
CF官方解法, 效率
设置一个结构体, struct P{int p, len, cost, type};
将每张票(l, r, cost)
表示成两个结构体, P(l, r-l+1, cost, -1), P(r, r-l+1, cost, 1);
设置一个数组best[i], 表示时间长度为i的最便宜的票, 一开始全为INF, 之后边用边更新
将结构体数字排序, 首先按p排序, p相同按type排序, 这样保证了是按时间顺序且同样时间type为-1的在type为1的前面
遍历整个结构体数组
type为1, 则用p[i].cost更新best[p[i].len]
type为-1, 则用p[i].cost+best[x-p[i].len]更新ans
因为数组按照p然后type排序, 保证了更新ans是用到的best[], 里面存储的都是根据时间段在之前的票得出的, 保证时间不会重叠
代码
#include <bits/stdc++.h>using namespace std;typedef long long ll;const int MAXN = 2E5 + 100, INF = 2e9+10;int n, x, l, r, c;int best[MAXN];struct P{ int p, len, cost, type; bool operator<(const P &x) { if(p == x.p) return type < x.type; return p < x.p; }}p[MAXN*2];int main(){ scanf("%d%d", &n, &x); int cnt = 0; for(int i=0; i<n; ++i) { scanf("%d%d%d", &l, &r, &c); p[cnt++] = P{l, r-l+1, c, -1}; p[cnt++] = P{r, r-l+1, c, 1}; } ll ans = INF; sort(p, p+cnt); fill(best, best+x, INF); for(int i=0; i<cnt; ++i) { if(p[i].type == -1) { if(p[i].len < x) { ans = min(ans, (ll)p[i].cost+(ll)best[x-p[i].len]); } } else best[p[i].len] = min(best[p[i].len], p[i].cost); } if(ans >= INF) ans = -1; cout << ans <<endl; return 0;}
2. 暴力
CF上看到好多人都是暴力过去的…
复杂
开一个vector<pair<int,int>> vp
, 长度为i的票存储在vp[i]里面, first表示开始时间l, second表示cost
然后循环1-x, 在两个循环遍历vp[i], vp[x-i], 检查时间是否重叠, 更新答案
把每个vp[i]根据l
排序一下, 可以优化一点
代码
#include <bits/stdc++.h>using namespace std;const int MAXN = 3E5 + 100, INF = 0X7FFFFFFF;int n, x, l, r, c;vector<pair<int, int>> vp[MAXN];int main(){ scanf("%d%d", &n, &x); for(int i=0; i<n; ++i) { scanf("%d%d%d", &l, &r, &c); vp[r-l+1].push_back({l, c}); } for(int i=0; i<=x; ++i) sort(vp[i].begin(), vp[i].end()); int ans = INF; for(int d=1; d<x; ++d) { int mn = INF; auto & u=vp[d], &v = vp[x-d]; for(int i=0, j=0; i<v.size(); ++i) { while(j<u.size() && u[j].first+d-1<v[i].first) { if(mn > u[j].second) mn = u[j].second; ++j; } if(mn != INF) { int s = mn + v[i].second; if(ans > s) ans = s; } } } if(ans == INF) cout << -1 << endl; else cout << ans << endl; return 0;}
- Codeforces Round #422 (Div. 2) C. Hacker, pack your bags! 排序, 贪心, 暴力(居然可以n方暴力)
- Codeforces Round #422 (Div. 2) C. Hacker, pack your bags!
- Codeforces Round #422 (Div. 2) C. Hacker, pack your bags!
- Codeforces Round #422 (Div. 2) C. Hacker, pack your bags! 思维排序或二分
- Hacker, pack your bags! Codeforces Round #422 (Div. 2) (贪心)
- Codeforces Round #422 (Div. 2) C. Hacker, pack your bags!(扫描线)
- Codeforces Round #422 (Div. 2) C Hacker, pack your bags! (二分orDP)
- codeforces #422 C. Hacker, pack your bags!(贪心dp)
- Codeforces Round #422 C. Hacker, pack your bags! (二分)
- Round 422 C. Hacker, pack your bags!
- Codeforces 822C Hacker, pack your bags!【排序+二分】
- codeforces 822 C Hacker, pack your bags!
- codeforces 882C Hacker, pack your bags!
- CodeForces 822C Hacker, pack your bags!
- cf #422 c Hacker, pack your bags! 【贪心】
- codeforces Hacker, pack your bags!
- Hacker, pack your bags! CodeForces
- Codeforces 822C Hacker, pack your bags!(思维+技巧)
- springMVC工作流程,带图
- 欢迎使用CSDN-markdown编辑器
- struts2_国际化的配置和操作
- ReactiveCocoa入门教程--第三部分
- solr 6.6 分词
- Codeforces Round #422 (Div. 2) C. Hacker, pack your bags! 排序, 贪心, 暴力(居然可以n方暴力)
- mysql 学习之列类型以及属性特点详解
- Cordova(PhoneGap)Android Native混合开发值传递
- 我的设计作品1
- AndroidStudio如何新建java工程?
- 葵花宝典 八 Struts2
- 【淘淘】---展示商品列表
- Avalon -- 使用错误集
- STM32---CAN2.0B读取新能源汽车BMS报文