CF 1398E Two Types of Spells(set,贪心)

本文解析CF1398E题目的解题思路,涉及两种技能“电”和“火”的伤害优化。通过贪心算法和数据结构set,讨论了如何合理安排技能使用顺序以达到最大伤害输出。代码实现中,运用了堆和set来动态维护伤害值最大的技能集合。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

CF 1398E Two Types of Spells(set,贪心)

传送门

题目大意

  有两种技能“电”和“火”,每种技能都有一个伤害值d,同时技能“电”可以使下一个使用的技能的伤害值提高一倍。每次你都会学习一个技能或者遗忘一个技能,问每次通过合理安排技能使用顺序能够造成最大伤害值是多少 。

解题思路

  首先考虑如何安排顺序使伤害值最大化,我们可以考虑将技能火按伤害值排序,然后将技能电按照从大到小的顺序插入技能火中。第一个插入的技能电一定会放在伤害值最大的技能火前面,然后用这个电的伤害替代后面火的伤害。再插入一个技能电,放在当前伤害最大的前面,再用插入的电的伤害替代后面技能的伤害。如此操作下来一定是最优的。再进一步考虑,我们发现那些被伤害被加倍的技能(假设电的个数为a个,也就是说最多a个技能能被加倍)一定包括一个伤害值最大的技能火,还有在剩下的技能中最大的a-1个技能。

代码实现

  为了方便维护被加倍的技能,我们只用维护伤害值最大的a个技能,如果这些技能全是电,那么我们就用伤害值最大的火替换掉这a个中伤害值最小的电。由于要支持删除操作,只用堆来维护是不行的,要改用set。具体细节请参考代码:

#include <bits/stdc++.h>
using namespace std;

long long sum, pre;
set<int> db, oc;
// db技能电,oc技能火
set<int> bg, sm;
// bg维护被加倍的技能 sm维护其它技能
void add(int d, int op) {
	sum += d;
	if (op == 1) db.insert(d); 
	else oc.insert(d);
	if (sm.empty() || d > *prev(sm.end())) bg.insert(d), pre += d;
	else sm.insert(d);
} 
void del(int d, int op) {
	sum -= d;
	if (op == 1) db.erase(d);
	else oc.erase(d);
	if (bg.count(d)) bg.erase(d), pre -= d; else sm.erase(d);
}
void maintain() {
	if (bg.size() > db.size()) {
		sm.insert(*bg.begin());
		pre -= *bg.begin();
		bg.erase(bg.begin());
	}
	if (bg.size() < db.size()) {
		bg.insert(*prev(sm.end()));
		pre += *prev(sm.end());
		sm.erase(prev(sm.end()));
	}
} 
int main() {
	int n;
	scanf("%d", &n);
	for (int d, op, i = 1; i <= n; i++) {
		scanf("%d%d", &op, &d);
		if (d < 0) del(-d, op);
		else add(d, op);
		maintain();
		if (oc.empty() && db.empty()) puts("0");
		else if (oc.empty() || (!db.empty() && *db.begin() >= *prev(oc.end()))) {
			long long ans = pre + sum - *db.begin();
			if (oc.size()) ans += *prev(oc.end());
			printf("%lld\n", ans); 
		}
		else printf("%lld\n", pre + sum);
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值