DOJ logoDOJ
题目
最近添加的题目收藏的题目Workbooks
分类DLC比赛小组团队讨论区
排名
解题数量排行榜连续解题排名DOJ Power 排行榜
评测状态
征题登录注册
DOJ logoDOJ

支持 OI 子任务计分、Elo 等级分和 Discord 认证的社区在线评测系统。

题目
题目列表分类
社区
比赛排名讨论区公告举办外部比赛指南
账号
登录注册评测状态
政策
服务条款DLC 使用规则隐私政策API 文档语言运行环境比赛排名奖励评级与表现
© 2026 DOJ
保留所有权利
题解

Binary String Reduction

返回题目

题解

문자열에 있는 1의 개수를 KKK라 하고, 왼쪽부터 iii번째 1의 위치를 xix_ixi​라 하자.

aaa번째부터 bbb번째까지의 1을 모두 포함하는 가장 짧은 구간을 연산에 사용하려면 다음 부등식이 필요하다.

xb−xa+1≤2(b−a+1)−1.x_b-x_a+1 \le 2(b-a+1)-1.xb​−xa​+1≤2(b−

이를 정리하면

xa−2a≥xb−2bx_a-2a \ge x_b-2bxa​−2a≥xb​−2b

가 된다. 편의상

qi=xi−2iq_i=x_i-2iqi​=xi​−2i

로 두자.

다음 점화식으로 정의되는 구간 [l,r][l,r][l,r]을 good이라고 하자.

g[l][l]=true.g[l][l]=\mathrm{true}.g[l][l]=true.

l<rl<rl<r일 때,

g[l][r]=(g[l+1][r]∧ql≥min⁡(ql+1,…,qr))∨(g[l][r−1]∧max⁡(ql,…,qr−1)≥qr).g[l][r] = \left(g[l+1][r] \land q_l \ge \min(q_{l+1},\ldots,q_r)\right) \lor \left(g[l][r-1] \land \max(q_l,\ldots,q_{r-1}) \ge q_r\right).g[l][r]=(

첫 번째 조건은 왼쪽 끝의 1을 먼저 지우는 경우이고, 두 번째 조건은 오른쪽 끝의 1을 먼저 지우는 경우이다.

lll을 감소시키는 순서로 순회하고 각 lll에 대해 rrr을 증가시키면, 필요한 최솟값과 최댓값을 누적하여 모든 g[l][r]g[l][r]g[l][r]을 O(K2)O(K^2)O(에 계산할 수 있다.

Lemma 1. 경계 바로 바깥에 0이 있는 good 구간은 내부의 1을 하나만 남길 수 있다.

구간 길이에 대해 귀납한다. 첫 번째 조건이 성립한다고 하자. ql≥qiq_l \ge q_iql​≥qi​를 만족하는 가장 가까운 iii를 고르면, lll번째 을 포함하여 조건을 만족하는 연산 구간을 잡아 왼쪽 끝의 을 지울 수 있다. 두 번째 조건이 성립하는 경우에는 대칭적으로 오른쪽 끝의 을 지울 수 있다. 그 뒤 더 짧은 good 구간에 귀납 가정을 적용한다.

Lemma 2. 구간 [a,b][a,b][a,b]가 good인 것과, 다음을 만족하는 a≤i≤j≤ba \le i \le j \le ba≤i≤j≤b가 존재하는 것은 동치이다.

qi=max⁡(qa,…,qb),qj=min⁡(qa,…,qb).q_i=\max(q_a,\ldots,q_b), \qquad q_j=\min(q_a,\ldots,q_b).qi​=max(qa​,

즉, 구간의 최댓값이 등장하는 어떤 위치가 구간의 최솟값이 등장하는 어떤 위치보다 앞이거나 같다. 이는 good의 점화식에 대해 구간 길이로 귀납하면 증명할 수 있다.

이제 dp[i]dp[i]dp[i]를 앞의 iii개 1을 good 구간들로 나누는 최소 구간 수라고 하자.

dp[0]=0,dp[0]=0,dp[0]=0, dp[r]=min⁡1≤l≤r, g[l][r](dp[l−1]+1).dp[r]=\min_{1 \le l \le r,\ g[l][r]}\left(dp[l-1]+1\right).dp[r]=1≤l≤r, g[l][r]

모든 good 구간을 이미 알고 있으므로 이 DP도 O(K2)O(K^2)O(K2)에 계산할 수 있다.

이제 dp[K]dp[K]dp[K]가 답임을 보이면 된다.

Lemma 3. 연산을 한 번 수행해도 최소 good 분할 수는 감소하지 않는다.

연산 전후의 qqq 배열을 각각 Q,Q′Q,Q'Q,Q′라 하자. 연산으로 하나의 1을 지우면 qqq 배열에서는 원소 하나가 사라지고, 그 오른쪽 원소들이 모두 222씩 증가한다.

이를 거꾸로 보면 Q′Q'Q′의 한 위치에 값 zzz를 삽입한 뒤, 그 오른쪽 접미사의 모든 값에서 222를 빼면 QQQ가 된다. 삽입 위치를 포함하지 않는 good 블록은 모든 값이 그대로이거나 모두 222씩 감소하므로 여전히 good이다.

삭제에 사용한 연산 구간의 양 끝 1을 a,ba,ba,b라 하면 qa≥qbq_a \ge q_bqa​≥qb​이다. 따라서

(qa−z)+(z−qb)=qa−qb≥0(q_a-z)+(z-q_b)=q_a-q_b \ge 0(qa​−z)+(z−qb

이므로 qa≥zq_a \ge zqa​≥z 또는 z≥qbz \ge q_bz≥qb​ 중 하나가 성립한다.

qa≥zq_a \ge zqa​≥z이면 삽입 위치의 왼쪽에서 zzz 이상인 값을 포함하는 최초의 블록까지 합친다. z≥qbz \ge q_bz≥q이면 오른쪽에서 이하인 값을 포함하는 최초의 블록까지 합친다. Lemma 2에 의해 합친 구간은 good이다.

삽입 위치가 블록 내부인 경우에도 qi+1−qi≥−1q_{i+1}-q_i \ge -1qi+1​−qi​≥−1을 이용하면, 삽입 전 블록이 good이면 삽입 후 블록도 good임을 Lemma 2로 보일 수 있다. 따라서 QQ의 최소 good 분할 수는 의 최소 good 분할 수보다 클 수 없다. 즉, 실제 연산을 할수록 최소 good 분할 수는 감소하지 않는다.

Lemma 4. 초기 qqq 배열의 최소 good 분할은 실제 연산으로 만들 수 있다.

최소 good 분할의 블록을 왼쪽부터 처리한다. S1=0S_1=\texttt{0}S1​=0이므로 첫 번째 블록의 왼쪽에는 0이 있어 Lemma 1을 적용할 수 있다.

한 블록을 1 하나로 줄인 뒤, 그 1이 다음 블록의 첫 번째 1과 붙어 있다고 하자. 두 1이 붙어 있으면 앞쪽 1의 qqq 값이 뒤쪽 1의 qqq 값보다 111 크므로, 앞쪽 1과 다음 good 블록을 합친 구간도 good이다. 이는 최소 good 분할의 블록 수를 더 줄일 수 있다는 뜻이므로 모순이다.

따라서 다음 블록의 왼쪽에는 항상 0이 존재하고, Lemma 1을 반복 적용하여 각 블록을 1 하나로 줄일 수 있다.

최종적으로 mmm개의 1이 남았다고 하자. 최종 배열은 길이 111인 good 구간 mmm개로 나눌 수 있다. Lemma 3을 반복 적용하면

dp[K]≤mdp[K] \le mdp[K]≤m

이다. 따라서 dp[K]dp[K]dp[K]보다 적은 수의 1을 남길 수 없다. 반대로 Lemma 4에 의해 정확히 dp[K]dp[K]dp[K]개의 1을 남길 수 있다.

그러므로 답은 dp[K]dp[K]dp[K]이다. K=0K=0K=0인 경우에는 답이 000이다.

각 테스트 케이스의 시간 복잡도는 O(N2)O(N^2)O(N2)이고, 공간 복잡도는 O(N2)O(N^2)O(N2)이다.

Solution written by GPT5.6

a+
1)−
1.
g
[
l
+
1
]
[
r
]
∧
ql​
≥
min
(
ql+1​
,
…
,
qr​
)
)
∨
(g[l][r−1]∧max(ql​,…,qr−1​)≥qr​).
K2
)
1
1
1
…
,
qb​
)
,
qj​
=
min(qa​,…,qb​).
min
​
(dp[l−1]+1)
.
​
)
=
qa​−
qb​≥
0
b
​
zzz
Q
Q′Q'Q′