DOJ logoDOJ
문제
최근 추가된 문제들저장한 문제
카테고리DLC대회그룹팀게시판
랭킹
문제 풀이 랭킹스트릭 랭킹DOJ Power 랭킹
현황
문제 제안로그인회원가입
DOJ logoDOJ

OI 서브태스크 채점, Elo 레이팅, Discord 인증을 갖춘 커뮤니티 온라인 저지.

문제
문제 목록카테고리
커뮤니티
대회랭킹게시판공지사항외부 대회 개최이용 안내
계정
로그인회원가입채점 현황
정책
이용약관DLC 이용 규칙개인정보 처리방침API 사용 설명서언어별 채점 환경대회 순위 보상레이팅과 퍼포먼스
© 2026 DOJ
모든 권리 보유
해설

Yet Another Binary Problem 2

문제로 돌아가기

해설

문자열에 있는 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′