PS❯BOJ2021-09-242 min read
[BOJ 1365] 꼬인 전깃줄 - Java (LIS 이분 탐색 Binary Search O(N log N))
전깃줄이 서로 꼬이지 않으려면 연결 번호가 증가 수열을 이루어야 하므로, O(N log N) 이분 탐색(lower bound) LIS를 구해 N - LIS_len을 잘라내는 풀이
#BOJ#LIS#이분탐색#그리디#Java
1. 문제 개요 및 조건 분석
| 항목 | 내용 |
|---|---|
| 문제 이름 | 꼬인 전깃줄 (백준 1365번 / 골드 2) |
| 플랫폼 / 난이도 | 백준 (골드 2, 1365번) |
| 문제 링크 | 백준 1365번 |
| 제한 사항 | 시간 제한 1초, 메모리 제한 128MB |
| 입력 조건 | 전봇대 개수 $N \le 100,000$, 연결되는 전봇대 번호 순열 |
| 핵심 규칙 | 전깃줄이 교차하지 않게 만들기 위해 잘라내야 하는 전깃줄의 최소 개수 계산 |
2. 접근 아이디어: $O(N \log N)$ LIS (이분 탐색)
전깃줄 교차 방지와 LIS
- 전깃줄이 꼬이지 않으려면 연결되는 전봇대 번호들이 **단조 증가 수열(LIS)**을 이루어야 합니다.
- 따라서 자를 전깃줄의 최소 개수 = 전체 전깃줄 수($N$) - 최장 증가 부분 수열의 길이(LIS).
- $N \le 100,000$이므로 $O(N^2)$ DP로는 시간 초과가 나며, 반드시 이분 탐색(Lower Bound)을 활용한 $O(N \log N)$ LIS 알고리즘을 사용해야 합니다.
3. Java 풀이 코드
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(br.readLine());
int[] lis = new int[n];
int len = 0;
StringTokenizer st = new StringTokenizer(br.readLine());
for (int i = 0; i < n; i++) {
int val = Integer.parseInt(st.nextToken());
int idx = Arrays.binarySearch(lis, 0, len, val);
if (idx < 0) idx = -(idx + 1);
lis[idx] = val;
if (idx == len) len++;
}
System.out.println(n - len);
}
}
4. 복잡도 분석
- 시간 복잡도: $O(N \log N)$ — 각 원소당 이분 탐색 $O(\log N)$. $N = 100,000$일 때 0.25초 이내에 완료.
- 공간 복잡도: $O(N)$ — LIS 배열.
5. 채점 결과 및 통과 인증

← PREVIOUS LOG
[BOJ 11722] 가장 긴 감소하는 부분 수열 - Java (LDS 동적 계획법)
NEXT LOG →[BOJ 14002] 가장 긴 증가하는 부분 수열 4 - Java (LIS DP & 역추적)
COMMENTS // GITHUB DISCUSSIONS (GISCUS)