题意:
有n个士兵,每个士兵 i 有武力值v[i]和限制人数s[i],即:若选择了第 i 个士兵则选择的总人数不能超过s[i]。求v[i]总和的最大值。
思路:
贪心,优先队列。按s[i]从大到小的顺序进行排序并遍历,对于每项v[i]直接入队。若size<=s[i]直接更新ans;若size>s[i]则最小项出队后更新ans。
此方案确保将v[i]足够大的留在队列中,同时也考虑到了v[i]大而s[i]小的情况。
代码:
#include <iostream> #include <queue> #include <set> #include <map> #include <vector> #include <stack> #include <cmath> #include <algorithm> #include <cstdio> #include <cctype> #include <functional> #include <string> #include <cstring> #include <sstream> using namespace std; typedef long long ll; typedef pair<int,int> P; typedef pair<int,P> Q; const int inf=2e9+9; const int maxn=1e5+9; const int maxx=2e5+9; int n; P ar[maxn]; bool cmp(P a,P b) { return a.second>b.second; } int main() { scanf("%d",&n); for(int i=0;i<n;i++) scanf("%d%d",&ar[i].first,&ar[i].second); sort(ar,ar+n,cmp); priority_queue<int,vector<int>,greater<int> > que; ll ans=0,tmp=0; for(int i=0;i<n;i++) { que.push(ar[i].first),tmp+=ar[i].first; while(que.size()>ar[i].second) tmp-=que.top(),que.pop(); ans=max(ans,tmp); } printf("%lld\n",ans); }