题目链接:https://ac.nowcoder.com/acm/problem/50995
题目大意:
图片说明
思路:贪心+优先队列:我们按时间从小到大排序,当前时间T。并且维护已经选取的商品的最小利润。如果当前商品的时间==T。那么从优先队列来里面找到最小值如果<当前商品的利润:替换。
如果当前商品的时间<T,直接选取。

思路:并查集:我们按商品的利润从大到小排序,那么我们希望从前往后贪心。并且把每个商品放在自己过期时间前越后越好。我们用并查集来维护时间。f[i]=-1:第i天空闲。否则f[x]=y。x前面第一个空闲的天数是f[y]。
如果找到空闲天x.维护f[x]=f[x-1]

1:
#include <bits/stdc++.h>
#define LL long long
using namespace std;

struct node{
    int w, t;
}a[10005];

priority_queue<LL, vector<LL>, greater<LL> > q;
int main(){
    int n;
    while(~scanf("%d", &n)){
        for(int i=1; i<=n; i++){
            scanf("%d%d", &a[i].w, &a[i].t);
        }
        sort(a+1, a+1+n, [](node &a, node &b){return a.t<b.t;});
        LL T=0, ans=0;
        for(int i=1; i<=n; i++){
            if(T<a[i].t){
                q.push(a[i].w);
                T++;
                ans+=a[i].w;
            }
            else if(a[i].w>q.top()){
                ans+=(a[i].w-q.top());
                q.pop(); q.push(a[i].w);
            }
        }
        printf("%lld\n", ans);
        while(!q.empty()){
            q.pop();
        }
    }

    return 0;
}
*****************************
2:
#include <bits/stdc++.h>
#define LL long long
using namespace std;

struct node{
    int w, t;
}a[10005];

int f[10005];
int fd(int x){
    if(f[x]==-1) return x;
    return f[x]=fd(f[x]);
}

int main(){
    int n;
    while(~scanf("%d", &n)){
        memset(f, -1, sizeof(f));
        for(int i=1; i<=n; i++){
            scanf("%d%d", &a[i].w, &a[i].t);
        }
        sort(a+1, a+1+n, [](node &a, node &b){return a.w>b.w;});
        LL ans=0;
        for(int i=1; i<=n; i++){
            int pos=fd(a[i].t);
            if(pos>0){
                ans+=a[i].w;
                f[pos]=pos-1;
            }
        }
        printf("%lld\n", ans);
    }

    return 0;
}