Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- level 3
- Lv. 1
- bfs
- Dynamic Programming
- DP
- 프로그래머스
- SQL 고득점 KIT
- programmers
- 백준
- 티스토리챌린지
- 깊이 우선 탐색
- Python
- SQL
- 너비 우선 탐색
- select
- Baekjoon
- javascript
- 오블완
- 소프티어
- Lv. 2
- Lv. 0
- dfs
- group by
- 자바스크립트
- Java
- softeer
- LEVEL 2
- join
- Lv. 3
- 파이썬
Archives
- Today
- Total
몸과 마음이 건전한 SW 개발자
백준 GOLD 5 [2565번] 전깃줄 {언어 : Python} [다시 풀어 보기] 본문
문제 링크
https://www.acmicpc.net/problem/2565
정답 코드
import sys
input = sys.stdin.readline
n = int(input())
lines = sorted([list(map(int, input().split())) for _ in range(n)], key=lambda x:x[1])
dp = [1] * n
for i in range(1, n):
si, ti = lines[i]
for j in range(i):
sj, tj = lines[j]
if sj < si:
dp[i] = max(dp[j]+1, dp[i])
print(n - max(dp))
풀이 방법
- 입력 처리 및 정렬
- (시작점, 끝점)을 입력받고 끝나는 지점 기준으로 정렬한다.
- 정렬은 그리디 + DP 조합을 활용하기 위한 사전 작업이다.
- DP 배열 정의 및 초기화
- dp[i]는 i번째 선분을 포함했을 때 겹치지 않는 최대 선분 개수를 저장한다.
- 모든 값은 최소 1이므로 [1] * n으로 초기화한다.
- DP 점화식 적용
- 이중 반복문을 돌며 sj < si 조건을 만족하는 경우 dp[i] = max(dp[j] + 1, dp[i])로 갱신한다.
- 즉, 선분이 겹치지 않는 경우 최대 선택 개수를 업데이트한다.
- 결과 출력
- max(dp)는 최대 겹치지 않는 선분 개수를 의미한다.
- 전체 개수 n에서 max(dp)를 빼면, 제거해야 할 최소 선분 개수가 된다.
lis 알고리즘
from bisect import bisect_left
import sys
input = sys.stdin.readline
n = int(input())
lines = sorted([list(map(int, input().split())) for _ in range(n)], key=lambda x:x[1])
lis = []
for si, _ in lines:
pos = bisect_left(lis, si) # lis에서 si가 들어갈 위치 찾기
if pos == len(lis):
lis.append(si) # 새로운 원소 추가
else:
lis[pos] = si # 기존 원소 교체 (LIS 유지)
print(n - len(lis)) # 제거해야 하는 최소 선분 개수
느낀점
- 기존 코드 (O(n^2)): DP를 이용해 최대 겹치지 않는 선분 개수를 구한다.
- 개선 코드 (O(n log n)): 이분 탐색 기반 LIS 알고리즘을 활용하여 최적화 가능하다.
- print(n - max(dp))를 통해 제거해야 할 최소 선분 개수를 출력하는 것이 핵심이다.
- 겹치는 부분을 구하려고 했으나 안 겹치는 부분의 개수를 구하면 쉬워지는 문제였다.
'알고리즘 > 다시 풀어 보기' 카테고리의 다른 글
백준 GOLD 5 [11729번] 하노이 탑 이동 순서 {언어 : Python} [다시 풀어 보기] (0) | 2025.02.14 |
---|---|
백준 GOLD 5 [9251번] LCS {언어 : Python} [다시 풀어 보기] (0) | 2025.02.13 |
백준 GOLD 5 [12865번] 평범한 배낭 {언어 : Python} [다시 풀어 보기] (0) | 2025.01.24 |
코드트리 | Two Pointer / 가장 짧은 부분합 {언어 : Python} [다시 풀어 보기] (0) | 2024.12.31 |
프로그래머스 [Lv. 4] 올바른 괄호의 갯수 {언어 : Python} [다시 풀어 보기] (0) | 2024.11.26 |