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