一开始想到了放炸弹烧草那道题,以为可以先对l进行排序使其尽量能走多少人就走多少人的贪心策略。但我忽略了走的并不一定是一个连续的区间。有可能因为走多了而导致浪费了一些。
那么从人上开始如果,对于每一个人选取一个服务线,那么如何选择服务线又成了一个贪心问题。选择服务线一定是选择r偏小的那一个,因为r小的话如果再不发挥作用就没机会了。如果r相同的话就选v小的那一个。因为有可能v比较小但r比较大,这时候可以将其放到后面发挥作用,如果放前面的话会浪费。
#include <bits/stdc++.h>
using namespace std;
struct Node {
int l, r, v;
bool operator < (const Node& node) const
{
if (node.r==r) return v>node.v;
return r>node.r;
}
};
//按左坐标从小到大排序
bool comp(Node n1, Node n2) {
return n1.l<n2.l;
}
int main() {
int n, m;
while(cin>>n>>m) {
priority_queue<Node> pq;
vector<Node> vt;
for (int i=0;i<m;i++) {
Node nd;
cin>>nd.l;
cin>>nd.r;
cin>>nd.v;
vt.push_back(nd);
}
sort(vt.begin(), vt.end(), comp);
int pos = 0, ans = 0;
for (int i=1;i<n;i++) {
//将满足l的进入到优先队列里面
while (pos<m&&vt[pos].l==i) {
pq.push(vt[pos]);
pos++;
}
//将v==0或者r<i的服务线从优先队列里面去除
while (!pq.empty()&&(pq.top().r<i||pq.top().v<=0)) {
pq.pop();
}
if (!pq.empty()) {
//将优先队列顶部的v的数目减一
Node tp = pq.top();
tp.v--;
pq.pop();
pq.push(tp);
ans++;
}
}
cout<<ans<<endl;
}
return 0;
}

京公网安备 11010502036488号