您的位置:首页 > Web前端

Codeforces 754 D Fedor and coupons

2017-06-03 12:06 387 查看
题目地址:http://codeforces.com/contest/754/problem/D

题意:你有n张优惠券,每张优惠券可以优惠一个范围的商品(l-r),你要选k张优惠券,使它优惠的区间最大

题解:我一开始没有什么好的方法,还以为是线段树之类的,可是没有思路去写,然后我看别人blog发现其实就是用一个数据结构维护k个值就好了,先按每张优惠券的l排序,再把前m-1张优惠券的r放入优先队列,再从第k小的开始判断能不能构成一个优惠区间,因为我ans的初值是0所以如果现在队列里最小的r比当前l还小的话cnt就是负数了,所以不会改变ans的值,详细可以看代码,个人觉得代码写的还是蛮清楚的

#include <iostream>
#include <cstring>
#include <string>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <algorithm>
#define N 300010
#define inf 0x3f3f3f3f
#define LL long long
using namespace std;
struct node {
int l, r, id;
}num
;
struct nope {
int num;
nope(int x) { num = x; }
bool friend operator < (nope a, nope b) {
return a.num > b.num;
}
};
bool cmp(node a, node b) {
if (a.l == b.l) {
return a.r < b.r;
}
return a.l < b.l;
}
int main() {
int n, m;
priority_queue<nope> q;
cin.sync_with_stdio(false);
while (cin >> n >> m) {
for (int i = 1; i <= n; i++) {
cin >> num[i].l >> num[i].r;
num[i].id = i;
}
while (!q.empty()) {
q.pop();
}
int cnt;
int ans = 0;
int l = 0;
sort(num + 1, num + n + 1, cmp);
for (int i = 1; i < m; i++) {
q.push(nope(num[i].r));
}
for (int i = m; i <= n; i++) {//至少要m张,所以前m-1张的l都是没有用的,所以直接到第m小的l开始判断
q.push(nope(num[i].r));
while (q.size() > m) {
q.pop();
}
cnt = q.top().num - num[i].l + 1;
if (cnt > ans&&q.size() == m) {
ans = cnt;
l = num[i].l;
}
}
cout << ans << endl;
if (ans) {
for (int i = 1; i <= n && m; i++) {
if (l >= num[i].l&&l + ans - 1 <= num[i].r) {
cout << num[i].id << " ";
m--;
}
}
cout << endl;
}
else {
for (int i = 1; i <= m; i++) {
cout << i << " ";
}
cout << endl;
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: