NC50439

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;
}
原文地址:https://www.cnblogs.com/LeafLove/p/13369918.html