题目链接 (找不到原题链接拿题解博客将就一下)
以下是我的想法:
预处理当前可以进行的C的次数最大值,然后整一个小根堆。从前往后搜索,如果堆没满就加进去,堆满了就比较堆顶元素和当前元素,考虑是否更换。最后答案就是堆中元素的和。但是这样做WA了三个点,不知道是哪里有问题(
代码
#include <queue>
#include <cstdio>
#include <vector>
#define min(a, b) (a < b ? a : b)
const int N = 2e5 + 5;
int n, sum, c[N], e[N], minn[N];
std :: priority_queue <int, std :: vector<int>, std :: greater<int> > q;
int main() {
freopen("dragons.in", "r", stdin);
freopen("dragons.out", "w", stdout);
scanf("%d", &n);
for(int i = 1, x; i <= n; i++) {
c[i] = -1;
char ch = getchar();
while(ch != 'c' && ch != 'e') ch = getchar();
scanf("%d", &x);
if(ch == 'c') c[i] = x;
if(ch == 'e') {
if(x <= 0 && i != n) {
printf("-1");
fclose(stdin); fclose(stdout);
return 0;
}
if(i != n) e[i] = x - 1;
//else e[i] = x;
}
}
minn[n + 1] = n + 1;
for(int i = n; i >= 1; i--) {
if(e[i]) minn[i] = min(minn[i + 1], e[i]);
else minn[i] = minn[i + 1];
}
for(int i = 1; i <= n; i++) {
if(c[i] >= 0) {
if(q.size() < minn[i]) q.push(c[i]);
else if(c[i] > q.top()) q.pop(), q.push(c[i]);
}
}
if(q.size() < e[n]) {
printf("-1");
fclose(stdin); fclose(stdout);
return 0;
}
while(!q.empty()) {
sum += q.top();
q.pop();
}
printf("%d", sum);
fclose(stdin); fclose(stdout);
return 0;
}