网络优化
题目大意
有一个区间,有
条网络,第
条网络的服务区间为
,但是它只能提供
个人的服务。
问:如何分配才能使得同一时间上线的人数最多?
分析
那么就考虑对于每一个点它是否能够被覆盖到,贪心即可。
那么贪心过程就可以是从左到右枚举区间上的每一个点,然后在符合条件的服务器中扣除一个人的服务。
那么如何来维护符合条件的服务器呢?
- 先将左右的服务器按左端点从小到大排序
- 将所有的
的服务器加入到优先队列中
- 把所有
或者不能再提供服务的服务器弹出
- 如果此时优先队列不为空,那么这个人可以上线,有
的贡献,将这个服务器的服务人数减一
- 如果此时优先队列为空,那么这个人无法上线了,没有贡献
- 如果此时优先队列不为空,那么这个人可以上线,有
时间复杂度大概是的
Code
#include <queue>
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn = 1e5 + 10;
inline int __read()
{
int x(0);
char o(getchar());
while (o < '0' || o > '9') o = getchar();
for (; o >= '0' && o <='9'; o = getchar())
x = (x << 1) + (x << 3) + (o ^ 48);
return x;
}
struct Node
{
int l, r, v;
bool operator < (const Node &T) const{
if (l == T.l && r == T.r) return v < T.v;
else if (l == T.l) return r < T.r;
return l < T.l;
}
}server[maxn];
struct Tree
{
int rest, r;
Tree () {}
Tree (int rest, int r) : rest(rest), r(r) {}
bool operator < (const Tree &T) const {
if (r == T.r) return rest > T.rest;
return r > T.r;
}
};
int n, m;
int main()
{
while (~scanf ("%d %d", &n, &m)) {
for (int i = 1; i <= m; ++i)
server[i].l = __read(), server[i].r = __read(), server[i].v = __read();
sort (server + 1, server + m + 1);
priority_queue <Tree> Q;
int cnt(1), ans(0);
for (int i = 1; i <= n; ++i) {
while (server[cnt].l == i) {
Q.push(Tree(server[cnt].v, server[cnt].r));
++cnt;
}
while (!Q.empty() && (Q.top().r < i || !Q.top().rest))
Q.pop();
if (Q.empty()) continue;
Tree T = Q.top();
T.rest--;
Q.pop();
Q.push(T);
++ans;
}
printf ("%d\n", ans);
}
} 
京公网安备 11010502036488号