考察知识点:贪心、优先队列

读入每个建筑的信息,按照每个建筑修理的截止时间 t2 升序排序,然后依次将建筑修理的时间 t1 加入优先队列(大根堆),同时维护当前建筑修理的时间之和 time,当当前建筑修理完成后的时间大于截止时间时,如果当前建筑所需的修理时间 t1 小于优先队列顶端的建筑所需的修理时间(即最长修理时间)时,则将当前建筑与优先队列顶端的建筑交换,同时更新 timetime - pq.top() + t1,最后的优先队列大小即为最多可修理的建筑数量。

时间复杂度

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<pii> vpii;
typedef vector<pll> vpll;

void solve()
{
    int n;
    cin >> n;
    vpll t(n);
    for (int i = 0; i < n; i++)
    {
        ll t1, t2;
        cin >> t1 >> t2;
        t[i] = {t2, t1};
    }
    sort(t.begin(), t.end());
    priority_queue<ll, vl, less<ll>> pq; // 大根堆
    ll time = 0;
    for (int i = 0; i < n; i++)
    {
        ll t1 = t[i].second, t2 = t[i].first;
        if (time + t1 <= t2)
        {
            pq.push(t1);
            time += t1;
        }
        else if (!pq.empty() && pq.top() > t1)
        {
            time -= pq.top() - t1;
            pq.pop();
            pq.push(t1);
        }
    }
    cout << pq.size() << endl;
}

signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int t = 1;
    // cin >> t;
    while (t--)
        solve();
    return 0;
}