아직 만들고 있는 페이지입니다.

이 페이지는 아직 만드는 중입니다. 보이는 내용은 바뀔 수 있습니다.

허프만의 욕심

시간 제한1초메모리 제한128 MB

요약
주어진 키와 간극의 빈도로 가중 비교 횟수를 최소화하는 최적 이진 탐색 트리를 만든다.
난이도

보통10점 중 7점

유형
동적 계획법, 트리, 구간, 누적 합
정답자
아직 제출이 없습니다

문제

트리에 관한 기본 용어부터 정의한다. 트리는 다음과 같이 귀납적으로 정의된다. 트리에는 루트가 있으며, 루트는 외부 노드(잎, leaf)이거나, 자식으로 여러 개의 트리를 갖는 내부 노드이다. 내부 노드는 자기 자식 트리들의 루트에 대한 부모라고 부른다. 노드의 레벨(level) 도 귀납적으로 정의된다. 루트의 레벨은 00이고, 다른 노드의 레벨은 그 부모의 레벨보다 11 크다.

이진 트리에서는 모든 내부 노드가 정확히 두 개의 자식, 즉 왼쪽 서브트리와 오른쪽 서브트리를 갖는다. 레이블이 붙은 이진 트리에서는 각 내부 노드가 문자열인 레이블을 추가로 갖는다. 이진 탐색 트리는 모든 내부 노드 tt가 다음 조건을 만족하는, 레이블이 붙은 이진 트리이다. tt의 왼쪽 서브트리에 있는 모든 레이블은 tt의 레이블보다 작고, tt의 레이블은 다시 오른쪽 서브트리에 있는 모든 레이블보다 작다. 비교는 문자열에 대한 사전식(알파벳) 순서를 사용한다.

중위 순회(inorder traversal) 는 잎을 만나면 그 잎을 방문하고, 내부 노드를 만나면 먼저 왼쪽 서브트리를 순회한 뒤 그 노드를 방문하고 마지막으로 오른쪽 서브트리를 순회한다. 따라서 이진 탐색 트리를 중위 순회하면 레이블이 사전식 순서대로 나열된다. 모양이 다른 이진 탐색 트리라도 중위 순회 결과는 같을 수 있다.

문자열 ss를 찾을 때는 현재 루트의 레이블 ll과 ss를 비교한다. s=ls = l이면 탐색을 끝내고, s<ls < l이면 왼쪽 서브트리에서, s>ls > l이면 오른쪽 서브트리에서 계속 찾는다. 잎에 도달하면 ss가 트리에 없다는 뜻이다.

비교 횟수는 ss와 트리의 모양에 따라 달라진다. 그러므로 주어진 문자열들을 저장하면서도 가능한 한 빠르게 접근할 수 있는 트리를 만들고자 한다. 어떤 문자열이 검색될지 미리 알 수 없으므로 확률 분포를 가정한다.

저장할 문자열의 개수를 nn이라 하고, 이 문자열들을 사전식 순서로 K1,…,KnK_1, \dots, K_n이라 하자. p1,…,pnp_1, \dots, p_n과 q0,…,qnq_0, \dots, q_n은 다음을 만족하는 2n+12n+1개의 음이 아닌 실수이다.

∑i=1npi+∑i=0nqi=1.\sum_{i=1}^{n} p_i + \sum_{i=0}^{n} q_i = 1.

이들의 의미는 다음과 같다.

  • pip_i = 검색 문자열 ss가 KiK_i와 같을 확률.
  • qiq_i = ss가 사전식으로 KiK_i와 Ki+1K_{i+1} 사이에 엄격히 놓일 확률.

관례상 q0q_0은 s<K1s < K_1일 확률이고, qnq_n은 s>Kns > K_n일 확률이다.

레이블 K1,…,KnK_1, \dots, K_n을 담으면서 기대 비교 횟수를 최소화하는 이진 탐색 트리를 찾고자 한다. 그 값은 다음과 같다.

cost=∑i=1npi⋅(1+level⁡(Ki))+∑i=0nqi⋅level⁡(ℓi),\mathrm{cost} = \sum_{i=1}^{n} p_i \cdot \big(1 + \operatorname{level}(K_i)\big) + \sum_{i=0}^{n} q_i \cdot \operatorname{level}(\ell_i),

여기서 ℓi\ell_i는 KiK_i와 Ki+1K_{i+1} 사이에 엄격히 놓이는 문자열을 찾을 때 도달하는 잎이며, 경계의 경우는 위의 관례를 따른다.

예를 들어 n=2n = 2이면 가능한 이진 탐색 트리의 모양은 정확히 두 가지이고, 정답은 그중 기대 비용이 더 작은 트리이다.

입력

입력은 여러 개의 테스트 케이스로 이루어진다. 각 테스트 케이스는 정수 nn으로 시작하며 1≤n≤2001 \le n \le 200이다. 이어서 2n+12n+1개의 음이 아닌 정수, 즉 빈도(frequency)가 주어진다. 이 빈도들의 합을 ss라 하면 1≤s≤1 000 0001 \le s \le 1\,000\,000이다. 확률 p1,…,pnp_1, \dots, p_n과 q0,…,qnq_0, \dots, q_n은 이 순서대로 각 빈도를 ss로 나누어 얻는다. 즉 처음 nn개의 빈도가 p1,…,pnp_1, \dots, p_n이고, 그다음 n+1n+1개의 빈도가 q0,…,qnq_0, \dots, q_n이다. 마지막 테스트 케이스 다음에는 00 하나가 주어진다.

출력

각 테스트 케이스에 대해, 주어진 빈도에 대한 어떤 이진 탐색 트리로도 달성할 수 있는 최소 기대 비교 횟수를 cost\mathrm{cost}라 할 때, 정수 cost⋅s\mathrm{cost} \cdot s를 한 줄에 출력한다.

예제2

  1. 예제 1

    입력
    2
    20 15 15 25 25
    35
    142 35 58 5 20 5 10 9 15 23 129 4 52 5 38 18 9 7 2 4 266 93 5 18 18 27 5 10 11 180 4 32 21 3 21
    0 55 27 36 85 31 58 3 334 0 98 27 113 89 180 0 62 12 0 37 0 3 64 70 0 277 0 0 0 170 0 18 76 27 3 29
    0
    
    예상 출력
    160
    13637
    
  2. 예제 2

    입력
    1
    10 20 30
    0
    
    예상 출력
    60