noip模拟赛 公交车
题目描述
LYK在玩一个游戏。
有k群小怪兽想乘坐公交车。第i群小怪兽想从xi出发乘坐公交车到yi。但公交车的容量只有M,而且这辆公交车只会从1号点行驶到n号点。
LYK想让小怪兽们尽可能的到达自己想去的地方。它想知道最多能满足多少小怪兽的要求。
当然一群小怪兽没必要一起上下车,它们是可以被分开来的。
输入格式(bus.in)
第一行三个数k,n,M。
接下来k行每行3个数xi,yi和ci。其中ci表示第i群小怪兽的小怪兽数量。
输出格式(bus.out)
一个数表示最多有多少只小怪兽能满足要求。
输入样例
3 5 3
1 3 4
3 5 2
1 5 3
输出样例
5
样例解释
第一群的3只小怪兽在1号点上车,并在3号点下车。
第二群的2只小怪兽在3号点上车,5号点下车。
数据范围
对于30%的数据小怪兽的总数不超过10只,n<=10。
对于另外30%的数据k,n<=1000。
对于100%的数据1<=n<=20000,1<=k<=50000,1<=M<=100,1<=ci<=100,1<=xi<yi<=n。
分析:把一群小怪兽看做一条有权值的线段,那么就把题目转化为了覆盖尽量多的线段,使他们尽量不想交,这就是一类经典的贪心问题了.
先把所有的线段按照右端点排序,用一个数组f记录第i个时刻车上已经有多少人了,因为是按照右端点排序的,所以每次加满人一定是最优的,因为加人是影响到后面的操作的,已经按照右端点排序了,所以对后面的影响最小,那么查询一下[x,y]中最多有多少人,然后把能放上的人全部放上去.
涉及到区间求最大值和区间修改,可以用线段树来优化.
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; int k, n, m, maxx[200010], tag[200010], ans; struct node { int x, y, c; }e[50010]; void pushup(int o) { maxx[o] = max(maxx[o * 2], maxx[o * 2 + 1]); } bool cmp(node a, node b) { if (a.y == b.y) return a.x > b.x; return a.y < b.y; } void pushdown(int o) { if (tag[o]) { tag[o * 2] += tag[o]; tag[o * 2 + 1] += tag[o]; maxx[o * 2] += tag[o]; maxx[o * 2 + 1] += tag[o]; tag[o] = 0; } } void update(int o, int l, int r, int x, int y, int v) { if (x <= l && r <= y) { tag[o] += v; maxx[o] += v; return; } pushdown(o); int mid = (l + r) >> 1; if (x <= mid) update(o * 2, l, mid, x, y, v); if (y > mid) update(o * 2 + 1, mid + 1, r, x, y, v); pushup(o); } int query(int o, int l, int r, int x, int y) { if (x <= l && r <= y) return maxx[o]; pushdown(o); int mid = (l + r) >> 1, res = 0; if (x <= mid) res = max(res, query(o * 2, l, mid, x, y)); if (y > mid) res = max(res, query(o * 2 + 1, mid + 1, r, x, y)); return res; } int main() { scanf("%d%d%d", &k, &n, &m); for (int i = 1; i <= k; i++) scanf("%d%d%d", &e[i].x, &e[i].y, &e[i].c); sort(e + 1, e + 1 + k, cmp); for (int i = 1; i <= k; i++) { int temp = query(1, 1, n, e[i].x, e[i].y), res = 0; if (temp >= m) continue; if (temp + e[i].c <= m) res = e[i].c; else res = m - temp; ans += res; update(1, 1, n, e[i].x, e[i].y - 1, res); } printf("%d\n", ans); return 0; }