백준 온라인 저지, 이진탐색 / 1365번: 꼬인전깃줄 (파이썬 / 백준 골드문제)
2021. 9. 1. 21:18ㆍ알고리즘/이진탐색
728x90
반응형
문제
https://www.acmicpc.net/problem/1365문제 정의
공화국에 있는 유스타운 시에서는 길을 사이에 두고 전봇대가 아래와 같이 두 줄로 늘어서 있다. 그리고 길 왼편과 길 오른편의 전봇대는 하나의 전선으로 연결되어 있다. 어떤 전봇대도 두 개 이상의 다른 전봇대와 연결되어 있지는 않다.
문제는 이 두 전봇대 사이에 있는 전깃줄이 매우 꼬여 있다는 점이다. 꼬여있는 전깃줄은 화재를 유발할 가능성이 있기 때문에 유스타운 시의 시장 임한수는 전격적으로 이 문제를 해결하기로 했다.
임한수는 꼬여 있는 전깃줄 중 몇 개를 적절히 잘라 내어 이 문제를 해결하기로 했다. 하지만 이미 설치해 놓은 전선이 아깝기 때문에 잘라내는 전선을 최소로 하여 꼬여 있는 전선이 하나도 없게 만들려고 한다.
유스타운 시의 시장 임한수를 도와 잘라내야 할 전선의 최소 개수를 구하는 프로그램을 작성하시오.
입력
첫 줄에 전봇대의 개수 N(1 ≤ N ≤ 100,000)이 주어지고, 이어서 N보다 작거나 같은 자연수가 N개 주어진다. i번째 줄에 입력되는 자연수는 길 왼쪽에 i번째 전봇대와 연결된 길 오른편의 전봇대가 몇 번 전봇대인지를 나타낸다.
출력
전선이 꼬이지 않으려면 최소 몇 개의 전선을 잘라내야 하는 지를 첫째 줄에 출력한다.
예제 입력 1
4 2 3 4 1
예제 출력 1
1
접근 방법
- 증가하는 부분수열로 로직을 작성한 뒤, N에서 가장 큰 값을 빼준다.
- 현재 탐색하는 수보다 앞에 있는 수 중 작은 수의 개수 + 1을 인덱스로 하는 리스트의 값에 작은 값을 입력한다.
코드
# https://www.acmicpc.net/status?user_id=gksqlsl11&problem_id=1365&from_mine=1
# 접근 방법
# 증가하는 부분수열로 로직을 작성한 뒤, N에서 가장 큰 값을 빼준다.
# 현재 탐색하는 수보다 앞에 있는 수 중 작은 수의 개수 + 1을 인덱스로 하는 리스트의 값에 작은 값을 입력한다.
n = int(input())
array = list(map(int, input().split()))
d = [n+1] * (n+1) # dp 테이블 초기화 / 인덱스 = 부분수열의 개수, 값 = 그 개수에 해당하는 전봇대 번호 중 더 작은 수
d[1] = array[0]
for x in array[1:]:
# 이진탐색 진행
start = 1
end = n + 1
index = 0
while start <= end:
mid = (start + end) // 2
if d[mid] < x: # 탐색 중인 수가 mid개의 부분수열을 가진 어떤 수보다 크다면
index = max(index, mid)
start = mid + 1
else:
end = mid - 1
# 현재 찾은 부분수열의 개수 인덱스의 값에 이를 저장(항상 탐색 중인 수는 다음 인덱스보다 작을 수밖에 없음)
d[index + 1] = x
# print(d)
for i in range(1, n + 1):
if d[i] == n + 1: # i : 부분 수열의 개수 + 1
break
print(n - (i - 1)) # 현재 주어진 전봇대의 수 - 부분 수열의 개수
728x90
반응형
'알고리즘 > 이진탐색' 카테고리의 다른 글
백준 온라인 저지, 이진탐색 / 2343번: 기타레슨 (파이썬) (0) | 2021.09.05 |
---|---|
백준 온라인 저지, 이진탐색 / 7795번: 먹을 것인가 먹힐 것인가 (파이썬 / 백준 골드문제) (0) | 2021.09.01 |
백준 온라인 저지, 이진탐색 / 1561번: 놀이공원 (파이썬 / 백준 골드문제) (0) | 2021.09.01 |
백준 온라인 저지, 이진탐색 / 1072번: 게임 (파이썬) (0) | 2021.09.01 |
백준 온라인 저지, 이진탐색 / 3745번: 오름세 (파이썬 / 백준 골드문제) (0) | 2021.08.30 |