tokitsukaze and Soldier(思维 贪心 )

tokitsukaze and Soldier

题目描述:
在一个游戏中,tokitsukaze需要在n个士兵中选出一些士兵组成一个团去打副本。
第 i 个士兵的战力为v[i],团的战力是团内所有士兵的战力之和。
但是这些士兵有特殊的要求:如果选了第 i 个士兵,这个士兵希望团的人数不超过 s[i]。(如果不选第i个士兵,就没有这个限制。)
tokitsukaze想知道,团的战力最大为多少。
数据范围:
第一行包含一个正整数n(1≤n≤10^5)。
接下来n行,每行包括2个正整数 v , s (1≤ v ≤10^9,1≤ s ≤n)。

官方题解

思路:排序,然后贪心。看到题目后第一时间想到用排序来做,但是要想到该如何排序,即该如何贪心是不太好想的。可以将士兵以 s 从大到小排序,然后将士兵依次入队列,直到入队的士兵的 s 小于队列当中的人数时,选择 v 较小的士兵弹出,直到其相等。在这遍历的过程中,维护队列里的 v 总和,然后取最大。(在这里的 priority_queue<LL , vector,greater >,使用的很巧妙)

#include<bits/stdc++.h>

using namespace std;
const int N = 1e5+7;
typedef long long LL;

struct node{
	LL v,s;
}a[N];

bool cmp(node a,node b){
	return a.s > b.s;
}
int main()
{
	LL n;
	cin>>n;
	for(int i=0;i<n;i++) cin>>a[i].v>>a[i].s;
	sort(a,a+n,cmp);	//以 s 从大到小排序
	
	priority_queue<LL , vector<LL> ,greater<LL> > q; 	//小根堆 
	LL cnt = 0 ,ans = 0; 
	for(int i=0;i<n;i++){
		cnt += a[i].v;		//始终代表堆里的v总和
		q.push(a[i].v);
		while(q.size() > a[i].s){	//相当于从大到小枚举个别 s 
			cnt -= q.top();
			q.pop();		//弹出栈顶 v 较小的
		}
		ans = max(ans,cnt);		//取最大值
	}
	cout<<ans<<endl;
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值