코딩테스트 파이썬/백준
스타트와 링크 ( 14889 번 )
세용용용용
2025. 10. 23. 20:51
🧠 알고리즘
- 백트래킹 (Backtracking)
✔️ 동작 방식
문제 핵심 아이디어: 스타트 팀과 링크 팀을 나누어 팀 점수 차이를 최소화
- 재귀 구조
- 재귀 함수 _bk(last_num, teams_count)를 이용해 스타트 팀의 멤버를 하나씩 선택
- visit[i] = False이면 i번째 사람을 스타트 팀에 포함
- 팀 구성 완료 시 점수 계산
- 스타트 팀: visit[i]가 True인 사람들
- 링크 팀: visit[i]가 False인 사람들
- 점수는 모든 팀원 쌍 (i,j)의 합을 계산
- 절대값 차이를 구해 answer 갱신
- 조기 종료
- 팀 점수 차이가 0이면 더 이상 볼 필요 없음 → exit()로 즉시 종료
- 재귀 탐색
- last_num부터 n까지 반복하면서 아직 선택되지 않은 사람을 스타트 팀에 추가
- 재귀 호출 후 상태 복원 (visit[i] = True)
- 최종 결과
- 모든 조합 탐색 후 최소 점수 차이를 출력
🧾 코드
import sys
def _bk(last_num, teams_count):
global answer
if teams_count == n // 2:
star, link = 0, 0
for i in range(n):
for j in range(n):
if i != j:
if visit[i] and visit[j]: # star 팀
star += map_list[i][j]
if not visit[i] and not visit[j]: # link 팀
link += map_list[i][j]
answer = min(answer, abs(star - link))
# 조기 종료
if answer == 0:
print(0)
exit()
return
for i in range(last_num, n):
if visit[i]:
visit[i] = False
_bk(i + 1, teams_count + 1)
visit[i] = True
n = int(sys.stdin.readline().rstrip())
map_list = [list(map(int, sys.stdin.readline().rstrip().split())) for _ in range(n)]
visit = [True] * n
answer = float('inf')
_bk(0, 0)
print(answer)
⏱️ 시간 복잡도
_bk(last_num, teams_count) : 벡트리킹 n//2 조합을 탐색 ( 지수형 시간 복잡도 )
# 내부 점수 계산 로직 ( 이차형 시간 복잡도 )
for i in range(n):
for j in range(n):
해당 알고리즘 시간 복잡도 : 지수형 시간 복잡도 ( O(2 ** n) * n **2 ) )