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'; }