思路
这道题我们可以利用贪心的思想。
我们这里把 a i a_i ai理解为第 a i a_i ai层灯。
在层数相同的灯被破坏之后,灯的个数就会减少到 0 0 0,所以它一定不会影响到之后下一层的灯。
所以,我们贪心的思路是:
将每一层(从第一层升序选)的灯的价值(即
b
i
b_i
bi)进行排序,对于该层没有被破坏的情况下,每一次选取在没有开着的灯中的价值的最大值
下面我们讲解一下为什么 a i a_i ai层不会影响到 a i + 1 a_i+1 ai+1层的灯:
红色为开着的点,假设我们这时又开了第三层的一个点:
此时第二层就会破坏了。
所以第三层还是可以亮三盏灯。
综上所述,在第 a i a_i ai层,就可以亮 a i a_i ai盏灯!
代码
#include <iostream>
#include <algorithm>
#include <vector>
#define int long long
using namespace std;
const int N = 2e5 + 10;
int Data;
int n, a, b;
vector<int> lamp[N];
signed main()
{
cin >> Data;
while (Data --)
{
cin >> n;
for (int i = 1; i <= n; i ++)
lamp[i].clear();
for (int i = 1; i <= n; i ++)
cin >> a >> b, lamp[a].push_back(b); //把这一层的点放入
for (int i = 1; i <= n; i ++)
sort(lamp[i].begin(), lamp[i].end()); //将这一层的价值排序
`
int lamps = 0, res = 0;
for (int i = 1; i <= n; i ++)
if (lamp[i].size()) //如果这一层有灯
for (int j = i, k = lamp[i].size() - 1; j && k >= 0; j --, k --) //因为是从小到大排序的,所以到这枚举!
res += lamp[i][k];
cout << res << endl;
}
}