题目描述
现在秦天通过入口关卡,同时也有其他人通过,下来是一个组队副本,现在有n个人通过入口关卡
第i个修士的战力为v[i],队伍的战力是队伍内所有修士的战力之和。
但是这些修士有特殊的要求:如果选了第i个修士,这个修士希望队伍的人数不超过s[i]。(如果不选第i个修士,就没有这个限制。)
秦天是这次带队师兄,现在要组一只队伍,他想知道最大的战力是多少
输入
第一行包含一个正整数n(1≤n≤10^5)。
接下来n行,每行包括2个正整数v,s(1≤v≤10^9,1≤s≤n)。
输出
输出一个正整数,表示团的最大战力。
样例输入
2
1 2
2 2
样例输出
3
思路:
可以先定义个结构体,里面包含v,s两个变量,输入各组数据后,先按s,也就是人数限制sort从大到小排序,这样是为了让后进队列的元素比先进队列的元素人数限制小,这样可以保证元素s变量与队列的size的兼容,对于排序后依次进队的元素,我们判断进队元素的s,和当前队列内的元素个数size,若s>size,则出队至size=s-1个元素,因为我们使用的是优先队列,且是按v战力值小的优先的(可以在结构体中重载运算符),所以出队队顶top始终是战力小的,以此来保证最高战力sum。详细的可看代码
代码:
#include <iostream>
#include <queue>
#include <algorithm>
using namespace std;
typedef struct node
{
long long int v,s;
bool operator < (const node & a) const
{
return v>a.v;
}
}node;
bool cmp(node a,node b)
{
return a.s>b.s;
}
node arr[100005];
int main()
{
long long int n,i,j;
cin>>n;
priority_queue<node> q;
long long int mxs = 0;
long long int mxv = 0;
long long int sum=0;
for(i=0;i<n;i++)
{
cin>>arr[i].v>>arr[i].s;
}
sort(arr,arr+n,cmp);
for(i=0;i<n;i++)
{
while(q.size()>=arr[i].s)
{
node t = q.top();
sum-=t.v;
q.pop();
}
q.push(arr[i]);
sum+=arr[i].v;
if(sum>mxs)
mxs = sum;
}
cout<<mxs<<endl;
return 0;
}