[Python] 28707 배열 정렬

2026. 1. 20. 16:44·Coding-Test/백준
728x90
반응형

[Gold I] 배열 정렬 - 28707 

[문제 링크](https://www.acmicpc.net/problem/28707)


💻 문제 정의

양의 정수로 이루어진 배열이 주어졌을 때, 해당 배열을 오름차순으로 정렬하려 한다. 배열 내 원소를 서로 교환할 때 비용이 든다. 이 배열을 정렬하기 위해 $M$가지 조작을 순서와 횟수에 상관없이 조작할 수 있다고 했을 때, 최소 비용으로 오름차순 정렬된 배열을 만들어라.

💡 접근 및 설계

최단경로 알고리즘을 활용하였다. 초기의 배열 상태에서 조작이 이루어지고 난 후의 상태를 구할 때 비용이 발생함으로 [비용, 조작 이후 배열 상태] 형태로 저장할 수 있다. 최소 비용을 구하는 것이 우리의 목적이므로 우선순위 힙을 활용하여 dijkstra를 구현하여 문제를 해결할 수 있겠다 생각하였다.

✏️ 알고리즘 풀이

N = int(input())
arr = [0] + list(map(int, input().split()))
tup_arr = tuple(arr)
M = int(input())

graph = []
for _ in range(M):
    a, b, cost = map(int, input().split())
    graph.append([a, b, cost])

weight = dict() # 가중치(비용) 저장 공간

초기 세팅은 다음과 같이 정의한다.

graph : 조작은 곧 간선과 비용을 의미한다. [a] → [b] 일때, 비용 cost를 함께 저장한다.

weight : 딕셔너리를 활용하였다. 현재 배열 상태를 key로, 그때의 상태를 만들기 위한 최소 비용이 value로 들어갈 것이다. 따라서 weight[정렬된 배열]을 구하는 것이 목표이다.

# 조작 함수
def swap(tup, left, right):
    lst = list(tup)
    lst[left], lst[right] = lst[right], lst[left]
    return tuple(lst)

조작(스왑) 함수이다. 현재의 배열 상태와 위치를 바꿀 두 개의 원소가 주어지면 스왑 후 반환해주는 함수이다.

# 최단 경로 함수
def dijkstra(tup):
    queue = []
    heapq.heappush(queue, [0, tup])
    weight[tup] = 0

    while queue:
        # curr_tup : 현재 상태, cost : 현재 상태를 만들었을 때 비용
        cost, curr_tup = heapq.heappop(queue)

        for l, r, c in graph:
            # 현재 상태에서 조작한 후
            next_tup = swap(curr_tup, l, r)

            # 바뀐 상태가 존재하지 않거나 더 비싼 비용으로 조작이 이루어졌을 경우
            if weight.get(next_tup) is None or weight[next_tup] > cost + c:
                # 비용 업데이트
                weight[next_tup] = cost + c
                # 큐에 저장
                heapq.heappush(queue, [weight[next_tup], next_tup])

현재 배열의 상태와 비용을 알고 있으면, 조작 이후의 상태 및 추가된 비용을 구하게 되어 queue에 저장된다. 각 상태마다 최적의 비용이 weight에 저장되어 최종적으로 정렬된 상태에서의 비용을 구할 수 있게 된다.

🗒️ 최종 제출 코드

# 28707 배열 정렬

import heapq

INF = 10_000_000

# 조작 함수
def swap(tup, left, right):
    lst = list(tup)
    lst[left], lst[right] = lst[right], lst[left]
    return tuple(lst)

# 최단 경로 함수
def dijkstra(tup):
    queue = []
    heapq.heappush(queue, [0, tup])
    weight[tup] = 0

    while queue:
        # curr_tup : 현재 상태, cost : 현재 상태를 만들었을 때 비용
        cost, curr_tup = heapq.heappop(queue)

        for l, r, c in graph:
            # 현재 상태에서 조작한 후
            next_tup = swap(curr_tup, l, r)

            # 바뀐 상태가 존재하지 않거나 더 비싼 비용으로 조작이 이루어졌을 경우
            if weight.get(next_tup) is None or weight[next_tup] > cost + c:
                # 비용 업데이트
                weight[next_tup] = cost + c
                # 큐에 저장
                heapq.heappush(queue, [weight[next_tup], next_tup])

N = int(input())
arr = [0] + list(map(int, input().split()))
tup_arr = tuple(arr)
M = int(input())

graph = []
for _ in range(M):
    a, b, cost = map(int, input().split())
    graph.append([a, b, cost])

weight = dict() # 가중치(비용) 저장 공간

dijkstra(tup_arr)

res = tuple(sorted(arr))
print(weight[res] if res in weight else -1)

💭 오늘의 회고

다익스트라 최단거리 개념을 다시 한 번 다잡게 되었다. 배열의 모든 경우를 하나의 노드로 보고, 상태 변화를 간선, 그때의 비용을 가중치로 두어 최단 거리 문제로 풀어나가는 것이 핵심 아이디어였던 것 같다.

728x90
반응형
저작자표시 (새창열림)

'Coding-Test > 백준' 카테고리의 다른 글

[Python] 16562 친구비  (0) 2026.01.31
[Python] 2234 성곽  (0) 2026.01.22
[Python] 9660 돌 게임 6  (0) 2026.01.20
[Python] 9661 돌 게임 7  (0) 2026.01.20
[Python] 9328 열쇠  (0) 2026.01.17
'Coding-Test/백준' 카테고리의 다른 글
  • [Python] 16562 친구비
  • [Python] 2234 성곽
  • [Python] 9660 돌 게임 6
  • [Python] 9661 돌 게임 7
희완
희완
희완한 코딩일상
    반응형
  • 희완
    Code-Heewan
    희완
  • 전체
    오늘
    어제
    • 분류 전체보기
      • Python
        • 가상환경
      • Algorithm
      • Coding-Test
        • 백준
        • 프로그래머스
        • 항해99
      • Data-Analysis
      • 웹 개발
        • django
      • AWS
      • 공모전
      • Mobile
  • 링크

    • Github
  • 300x250
  • hELLO· Designed By정상우.v4.10.3
희완
[Python] 28707 배열 정렬
상단으로

티스토리툴바