CF1804D Accommodation 题解

Description

link

Solution

由于行与行之间独立,所以可以对每行分别求最大和最小值。

先考虑最小值。

先找出每段 11 的长度,显然是尽量往里面放双人房,如果所需双人房个数 >m4>\dfrac{m}{4},那么就删掉一些双人房然后塞单人房即可。

然后是最大值。

11 的个数为 cc,那么答案就是 cc 减双人房中两个都是 11 的房间个数。

考虑双人房中两个都是 11 的最小房间个数怎么求,由于这个又等于 m4\dfrac{m}{4} 减双人房中有至少一个为 00 房间个数。

至少一个为 00 的个数就从前往后扫,如果发现 ai+ai+1<2a_i+a_{i+1}<2 就用双人房,然后跳到 i+2i+2 继续搞。

这样做显然是对的,证明如下:

考虑把 00 和他们两边的 11 的区间最边上的 11 合并成一个大区间 [li,ri][l_i,r_i],如果两个 00 区间中间只隔了 1111 那么把他们也合并了。

容易发现区间不会相交。上面那个操作就是在每个区间里找最多不相交的二连线段个数,显然从前往后扫是最优的。

至少一个为 00 的个数如果大于 m4\dfrac{m}{4} 就取到 m4\dfrac{m}{4}

时间复杂度:O(nm)O(nm)

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#include <cstdio>
#include <iostream>

// #define int long long

const int kMaxN = 5e5 + 5;

int n, m;
int a[kMaxN], b[kMaxN];

int getmin(std::string s) {
int cnt2 = m / 4, k = 0;
for (int i = 1; i <= m; ++i)
a[i] = s[i] - '0';
int lst = 0;
for (int i = 1; i <= m; ++i) {
if (a[i]) ++lst;
if (!a[i + 1] && lst) {
b[++k] = lst, lst = 0;
}
}
int sum = 0, tot = 0;
for (int i = 1; i <= k; ++i) {
sum += b[i] / 2;
tot += b[i];
}
if (sum <= cnt2) return sum + tot - 2 * sum;
else return cnt2 + tot - 2 * cnt2;
}

int getmax(std::string s) {
int cnt2 = m / 4, k = 0, ret = 0;
for (int i = 1; i <= m; ++i) {
a[i] = s[i] - '0';
ret += a[i];
}
for (int i = 1; i < m;) {
if (!a[i] || !a[i + 1]) {
++k, i += 2;
} else {
++i;
}
}
return ret - (cnt2 - std::min(cnt2, k));
}

void dickdreamer() {
int mi = 0, mx = 0;
std::cin >> n >> m;
for (int i = 1; i <= n; ++i) {
std::string s;
std::cin >> s;
s = " " + s;
mi += getmin(s), mx += getmax(s);
}
std::cout << mi << ' ' << mx << '\n';
}

int32_t main() {
#ifdef ORZXKR
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#endif
std::ios::sync_with_stdio(0), std::cin.tie(0), std::cout.tie(0);
int T = 1;
// std::cin >> T;
while (T--) dickdreamer();
// std::cerr << 1.0 * clock() / CLOCKS_PER_SEC << 's' << std::endl;
return 0;
}

CF1804D Accommodation 题解
https://sobaliuziao.github.io/2023/06/27/post/dd4d314d.html
作者
Egg_laying_master
发布于
2023年6月27日
许可协议