题目 | Ignore Operations
Monoxer Programming Contest 2022(AtCoder Beginner Contest 249)
F - Ignore Operations
https://atcoder.jp/contests/abc249/tasks/abc249_f
Time Limit: 2 sec / Memory Limit: 1024 MB
Score : $500$ points
Problem Statement
Takahashi has an integer $x$. Initially, $x = 0$.
There are $N$ operations. The $i$-th operation $(1 \leq i \leq N)$ is represented by two integers $t_i$ and $y_i$ as follows:
- If $t_i = 1$, replace $x$ with $y_i$.
- If $t_i = 2$, replace $x$ with $x + y_i$.
Takahashi may skip any number between $0$ and $K$ (inclusive) of the operations. When he performs the remaining operations once each without changing the order, find the maximum possible final value of $x$
Constraints
- $1 \leq N \leq 2 \times 10^5$
- $0 \leq K \leq N$
- $t_i \in \{1,2\} \, (1 \leq i \leq N)$
- $|y_i| \leq 10^9 \, (1 \leq i \leq N)$
- All values in input are integers.
Input
Input is given from Standard Input in the following format:
$N$ $K$
$t_1$ $y_1$
$\vdots$
$t_N$ $y_N$
Output
Print the answer.
Sample Input 1
5 1
2 4
2 -3
1 2
2 1
2 -3
Sample Output 1
3
If he skips the $5$-th operation, $x$ changes as $0 \rightarrow 4 \rightarrow 1 \rightarrow 2 \rightarrow 3$, so $x$ results in $3$. This is the maximum.
Sample Input 2
1 0
2 -1000000000
Sample Output 2
-1000000000
Sample Input 3
10 3
2 3
2 -1
1 4
2 -1
2 5
2 -9
2 2
1 -6
2 5
2 -3
Sample Output 3
15
我的笔记
对于操作 $1$,需要知道的性质是:如果选择了该操作的数字,那么该操作之前的所有操作都是无意义的,不会影响结果。
反向遍历所有操作:
对于操作 $2$,如果数字 $\geq0$,那么当然收下,加到 $added$ 里面。如果数字 $<0$,那么暂存在一个大根堆内。
对于操作 $1$,如果不跳过该操作,计算一次 $ans=\max(ans,y_i+added)$。然后再跳过该操作,$K$ 减一。
然后需要判断堆的大小。
如果堆的大小 $\leq$ 当前还能跳过的次数,那么就可以把所有的都跳过,避免加负数到 $added$ 内。如果堆的大小 $>$ 当前还能跳过的次数,那么就只能加最大的负数到 $added$ 内。
注意如果结束时 $K>=0$,还需计算一次 $ans=\max(ans,y_i+added)$,防止初始为 $0$ 的情况遗漏。
代码
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 2e5 + 10;
int N, K;
int t[MAXN], y[MAXN];
priority_queue<int> pque;
int main()
{
cin >> N >> K;
for (int i = N; i > 0; i--)
cin >> t[i] >> y[i];
long long ans = INT64_MIN, added = 0;
for (int i = 1; i <= N; i++)
{
if (t[i] == 2)
{
if (y[i] >= 0)
added += y[i];
else
pque.push(y[i]);
}
else
{
ans = max(ans, y[i] + added);
K--;
}
while (pque.size() > K)
{
added += pque.top();
pque.pop();
}
if (K < 0)
break;
}
if (K >= 0)
ans = max(ans, added);
cout << ans << endl;
return 0;
}
本文采用 CC BY-SA 4.0 许可,本文 Markdown 源码:Haotian-BiJi