一开始想到了放炸弹烧草那道题,以为可以先对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; }