题意:

在每个士兵都有一个对团队人数的限制下,选出战斗力最高的一个团队

思路:

根据每个士兵对团队人数限制的大小,从人数多的到少的,枚举一下对每个人的判断,看一下这个人要不要进来,进来后要不要把一些人删掉。如果人数超了,肯定是要把队里战力最小的拿出去,就可以用一个小根堆来维护。这样维护只要每次删除一些人,或者不加一些人进来,删除一些人肯定是比增加一些人方便的,并且一个团队的大小是由最小的团队人数决定的,这样就相当于把所有的团队组成形式列举出来,选出当前团队人数的战力最大值。

代码:

#include<iostream>
#include<queue>
#include<algorithm>
#include<cmath>
using namespace std;
#define PII pair<int,int>
#define ll long long
#define x first
#define y second
priority_queue<int,vector<int>,greater<int>> q;
const int N=100100;
PII t[N];

bool cmp(PII a,PII b)
{
    return a.y>b.y;
    return a.x>b.x;
}
int main(){
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++) 
    {
        int a,b;
        scanf("%d%d",&a,&b);
        t[i]={a,b};
    }
    sort(t+1,t+n+1,cmp);
    ll ans=0,num=0;//num是每个时刻的情况
    for(int i=1;i<=n;i++)
    {
        q.push(t[i].x);//不管这个士兵的战力,先放进来,让优先队列来排序,如果人数超了,把堆顶元素弹出,也就是把最小的元素丢掉,直到符合此时的人数限制
        num+=t[i].x;
        while(q.size()>t[i].y)
        {
            num-=q.top();
            q.pop();
        }
        ans=max(ans,num);//每次更新答案
        
    }
    printf("%lld\n",ans);
    
    
    return 0;
}