CodeForces-1132C 题解

题目传送门

一道枚举题……

我们可以直接枚举那 22 个去掉的粉刷匠。先统计一下每个栅栏会被多少个粉刷匠刷到,然后枚举第一个被去掉的粉刷匠,然后计算剩下的粉刷匠会将每个栅栏刷到多少次,我们只需要看只能被刷 11 次的栅栏就行了。

接着处理一个前缀和数组,记录前 ii 个栅栏中有多少个只能被 11 个粉刷匠刷到。然后枚举第二个被去掉的粉刷匠,然后通过前缀和用 O(1)O(1) 的时间复杂度查询,别忘了加上前面第一个粉刷匠去掉后没有被刷的栅栏的数量。最后取最小值,与 nn 相减即是答案。

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <bits/stdc++.h>
#define ll long long
#define INF 1e9
using namespace std;
int n, q, minn = INF;
int l[5005], r[5005], cnt[5005], sum[5005];
signed main() {
ios :: sync_with_stdio(0);
cin >> n >> q;
for (int i = 1; i <= q; i++) {
cin >> l[i] >> r[i];
for (int j = l[i]; j <= r[i]; j++) cnt[j]++;
}
for (int i = 1; i <= q; i++) {
int x = 0;
for (int j = l[i]; j <= r[i]; j++) cnt[j]--;
for (int j = 1; j <= n; j++) {
sum[j] = sum[j - 1];
if (cnt[j] == 1) sum[j]++;
if (cnt[j] == 0) x++;
}
for (int j = 1; j <= q; j++) {
if (j == i) continue;
minn = min(minn, sum[r[j]] - sum[l[j] - 1] + x);
}
for (int j = l[i]; j <= r[i]; j++) cnt[j]++; // 别忘了要加回去继续枚举
}
cout << n - minn;
return 0;
}