CF1839B题解
-
分析
根据题意,对于所有\(a=x\)的灯,我们最多可以一次开\(x\)盏。
最优方案一定是只开\(a\)相同的灯,因为开一盏大的会使等于\(a\)的灯少开一盏,而且最后不会坏掉,会一直占着一个名额,从而使当前\(a\)一直到更大的\(a\)的轮次一直少开一盏,这个亏损必定大于等于多开一盏大\(a\)轮次的灯所带来的利益(因为不提前开这个灯在他自己的\(a\)的轮次还是可以开包括这个灯在内的\(a\)盏灯,而提前开这个灯就不会在自己的轮次开,而且只能开\(a-1\)盏,所以总利润还是\(a\)盏灯的利润,而且提前的轮数到当前的轮数会一直亏损一盏灯的利润,所以亏损必定大于等于利润),所以不开大的,小的可以看做在小的轮次里面开大的,这已经知道是必定不赚的决策了,所以只开\(a\)相同的。
显然对于所有\(a=x\)的灯,我们选\(b\)最大的\(x\)盏灯就行,注意到\(b\)最大为\(1e9\),所以开long long。
-
代码
#include <iostream>
#include <vector>
#include <algorithm>
#define int long long
using namespace std;
constexpr int MAXN(1000007);
vector <int> e[MAXN];
int T, n;
inline void read(int &temp) { cin >> temp; }
inline bool cmp(int x, int y) { return x > y; }
inline void work() {
for (int i(1); i <= n; ++i) e[i].clear();
int ans(0);
read(n);
for (int i(1), a, b; i <= n; ++i) read(a), read(b), e[a].push_back(b);
for (int i(1); i <= n; ++i) sort(e[i].begin(), e[i].end(), cmp);
for (int i(1); i <= n; ++i) {
if (!e[i].size()) continue;
for (int j(0); j < min(i, (int)e[i].size()); ++j) ans += e[i][j];
}
cout << ans << endl;
}
signed main() {
ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
read(T);
while (T--) work();
return 0;
}