Solution

非常显然的离线+优先队列求解,先处理更加“宽容”的人(希望士兵团不超过的人数更多的人),那么那些不那么“宽容”的被分配到团中时,比这个人更加“宽容”的人也能分配到团中。

限定一个值,让都堆在一起后,选择前大的求和即是此时所能安排的最大值。这是经典的topK问题。

的取值有个,所以直接枚举的复杂度是的。但如果从大的开始安排的话,会发现枚举的元素是在原来的基础上增加而已。那么问题就变成了动态的topK问题了。复杂度变为了

他给的输入不是按照递减的顺序给的,那么排一下序就可以了。

Code

#include<bits/stdc++.h>
using namespace std;
int main() {
  ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
  int n; cin >> n;
  priority_queue<int, vector<int>, greater<int>> q;
  vector<pair<int, int>> v(n);
  for(int i = 0; i < n; i++) {
    cin >> v[i].second >> v[i].first;
  }
  sort(v.begin(), v.end());
  reverse(v.begin(), v.end());
  long long sum = 0, ans = 0;
  for(int i = n, j = 0; i >= 1; i--) {
    while(j < n && v[j].first >= i) {
      q.push(v[j].second);
      sum += v[j].second;
      j++;
    }
    while(int(q.size()) > i) {
      sum -= q.top();
      q.pop();
    }
    ans = max(ans, sum);
  }
  cout << ans << '\n';
}