[贪心+优先队列] tokitsukaze and Soldier
题目
思路
先按容纳(宽容程度)限度从大到小排序。这样可以保证比当前数更宽容的人被加入到堆里面。
然后一个个加入堆里面,如果当前要加入的人的限度比当前堆已有人数少,那就一直弹出堆里面的最小价值的元素知道可以把当前的加进去。看别人说就是一个动态TOP-K问题,动态维护一下答案即可。
代码
#include<bits/stdc++.h>
using namespace std;
#define endl "\n"
typedef long long LL;
typedef pair<int,int> PII;
/*DATA & KEY
n 1 1e5
v 1 1e9
s 1 n
*/
int T;
const int N=1e5+10;
struct Node
{
LL v,s;
}a[N];
bool cmp(Node a,Node b)
{
return a.s>b.s;
}
void solve()
{
//NEW DATA CLEAN
//NOTE!!!
LL n;scanf("%lld",&n);
for(int i=1;i<=n;i++)
scanf("%lld%lld",&a[i].v,&a[i].s);
sort(a+1,a+1+n,cmp);
priority_queue<int,vector<int>,greater<int> >heap;
LL ans=0,sum=0;
for(int i=1;i<=n;i++)
{
if(heap.size()<a[i].s)
{
heap.push(a[i].v);
sum+=a[i].v;
}
else
{
while(heap.size()>=a[i].s)
{
sum-=heap.top();
heap.pop();
}
heap.push(a[i].v);
sum+=a[i].v;
}
ans=max(ans,sum);
}
cout<<ans<<endl;
}
int main()
{
// scanf("%d",&T);
// while(T--)solve(T);
solve();
return 0;
}