Npc50C [贪心]
在一个游戏中,tokitsukaze需要在n个士兵中选出一些士兵组成一个团去打副本。
第i个士兵的战力为v[i],团的战力是团内所有士兵的战力之和。
但是这些士兵有特殊的要求:如果选了第i个士兵,这个士兵希望团的人数不超过s[i]。(如果不选第i个士兵,就没有这个限制。)
tokitsukaze想知道,团的战力最大为多少。
发现如果按照 从大到小贪心的话, 团的人数限制不好处理, 因为不知道是哪个士兵限制了团的人数大小 .
于是按照 从大到小排序, 从左往右选择士兵, 限制团大小的士兵肯定包括 和 与 相等的士兵,
在 这个士兵的限制下, 要尽量使得战力更大, 即选择最大的, 丢弃最小的,
于是可以使用小根堆维护当前的士兵集合, 若不符合条件, 就不断地往外弹出 最小的士兵, 直到符合条件, 更新答案 .
#include<bits/stdc++.h>
typedef long long ll;
#define reg register
const int maxn = 1e5 + 10;
int N;
ll Ans;
ll cur_sum;
struct Node{ int s, v; } A[maxn];
bool cmp(Node a, Node b){ return a.s > b.s; }
int main(){
scanf("%d", &N);
for(reg int i = 1; i <= N; i ++) scanf("%d%d", &A[i].v, &A[i].s);
std::sort(A+1, A+N+1, cmp);
std::priority_queue <int, std::vector<int>, std::greater<int> > Q;
for(reg int i= 1; i <= N; i ++){
Q.push(A[i].v), cur_sum += A[i].v;
while((int)Q.size() > A[i].s) cur_sum -= Q.top(), Q.pop();
Ans = std::max(Ans, cur_sum);
}
printf("%lld\n", Ans);
return 0;
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步