CF1839B Lamps

思路

这道题我们可以利用贪心的思想。

我们这里把 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层的灯:

CF1839B Lamps_第1张图片

红色为开着的点,假设我们这时又开了第三层的一个点:

CF1839B Lamps_第2张图片

此时第二层就会破坏了。
所以第三层还是可以亮三盏灯。

综上所述,在第 a i a_i ai层,就可以亮 a i a_i ai盏灯!


代码

#include 
#include 
#include 
#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;
	}
}

你可能感兴趣的:(数学,算法-暴力,算法-贪心,算法)