NC50439
题目链接:https://ac.nowcoder.com/acm/problem/50439
题解:
每次放入一个新的士兵都要考虑当前状态是否满足,如果我们无规律的去加入士兵,我们便无法确定当前应该把那些士兵排除,考虑将士兵的s约束从大大小排序,这样我们每次加入士兵,都会只能是将当前的团队人数降低,所以每次只需要考虑去除那些士兵,因为要取到最大的战力,所以每次去除的应该是战力最小的几个,所以总体看来只需要对数列按s从大到小排序,然后优先队列维护团队。
Code:
/**********************************************************
* @Author: Kirito
* @Date: 2020-07-24 07:46:21
* @Last Modified by: Kirito
* @Last Modified time: 2020-07-24 07:51:25
* @Remark:
**********************************************************/
#include <bits/stdc++.h>
#define lowbit(x) (x&(-x))
#define CSE(x,y) memset(x,y,sizeof(x))
#define INF 0x3f3f3f3f
#define Abs(x) (x>=0?x:(-x))
#define FAST ios::sync_with_stdio(false);cin.tie(0);
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll , ll> pll;
const int maxn=111111;
struct node{
ll v;
int s;
bool operator < (const node &b)const{
return s>b.s;
}
}arr[maxn];
priority_queue<ll,vector<ll>,greater<ll>> box;
int n;
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.in","r",stdin);
#endif
cin>>n;
for(int i=0;i<n;i++)
cin>>arr[i].v>>arr[i].s;
sort(arr,arr+n);
ll ans=0,tmp=0;
for(int i=0;i<n;i++){
box.push(arr[i].v);
tmp+=arr[i].v;
while(box.size()>arr[i].s){
tmp-=box.top();
box.pop();
}
ans=max(ans,tmp);
}
cout<<ans<<endl;
return 0;
}