Coding Test/BaekJoon_Python
백준 11066 <파일 합치기> Python
JunOnJuly
2023. 12. 4. 17:57
728x90
https://www.acmicpc.net/problem/11066
11066번: 파일 합치기
소설가인 김대전은 소설을 여러 장(chapter)으로 나누어 쓰는데, 각 장은 각각 다른 파일에 저장하곤 한다. 소설의 모든 장을 쓰고 나서는 각 장이 쓰여진 파일을 합쳐서 최종적으로 소설의 완성본
www.acmicpc.net
3중 반복문을 기본으로 하는 풀이입니다. i 개의 데이터를 더하고 j 에서 시작하며 k 에서 끊어서 더하는 3중 반복문입니다.
[a0, a1, ... , an] 의 전체 데이터를 두고 최소 코스트를 구한다고 가정하겠습니다.
<i> 처음으로 2 개의 데이터를 더하는 경우부터 시작해 n+1 개의 데이터를 더하는 경우까지 확장합니다.
<j> 처음 시작하는 데이터의 인덱스는 0부터 n+1-i 까지 입니다.
<k> 끊어지는 데이터의 인덱스는 0 부터 j+i 즉 시작 지점부터 데이터의 개수를 더한 값입니다.
즉 i == 3, j == 2, k == 1 인 경우 [a2, a3], [a4] 으로 쪼개어 비교하는 식입니다.
이런 식으로 쪼개어 계산하는 이유는 [a0, a1, ... , an] 의 데이터가 주어질 때 끊어서 계산하는 위치에 따라 값이 달라지기에 모두 순회하며 비교하기 때문입니다.
import sys
from collections import deque
def solution(K, data_list):
# data_list 를 어디서 끊어낼지 정하는 문제
# i~j, j~k 까지 끊어낸 합 중 최대를 구하면 됨
# DP, memo[i][j] 는 i 에서 j 까지 최소 코스트
# memo[i][i] 는 0
memo = [[1e9 for _ in range(K)] for __ in range(K)]
for idx in range(K):
memo[idx][idx] = 0
# 누적합
subsum = [0] + data_list
for idx in range(len(subsum)):
if idx:
subsum[idx] += subsum[idx-1]
# i~j 까지의 길이
for i in range(2, K+1):
# 시작하는 지점
for j in range(K-i+1):
# 끊어지는 지점
for k in range(j, j+i-1):
# 비교
# 예를들어 [1, 2, 3] 이면
# [1], [2, 3] 으로 끊는 것과
# [1, 2], [3] 으로 끊는 것을 비교
# 누적합을 더해주는 이유는
# [1], [2, 3] 인 경우
# [1], [5] -> [6] 의 과정에서
# 중간에 더해지는 코스트인 [2, 3] 을 더해주기 위함
memo[j][j+i-1] = min(memo[j][j+i-1], memo[j][k] + memo[k+1][j+i-1] + subsum[j+i] - subsum[j])
print(memo[0][K-1])
T = int(sys.stdin.readline().strip())
for _ in range(T):
K = int(sys.stdin.readline().strip())
data_list = list(map(int, sys.stdin.readline().strip().split()))
solution(K, data_list)
728x90