허프만 되돌리기
시간 제한1초메모리 제한128 MB
어떤 허프만 실행으로 나올 수 있는 코드 길이가 주어지면 그 길이를 만드는 가장 작은 전체 문자 수를 구합니다.
문제
정적 허프만 부호화는 주로 텍스트 압축에 쓰는 부호화 알고리즘이다. 서로 다른 문자 개로 이루어진 텍스트가 주어지면, 알고리즘은 문자마다 부호를 하나씩 정해 개의 부호를 고르고 그 부호로 텍스트를 압축한다. 부호를 고르려고 알고리즘은 잎이 개인 이진 루트 트리를 만든다. 인 경우 트리는 다음 순서로 만든다.
- 텍스트에 나오는 서로 다른 문자마다 노드가 하나뿐인 트리를 만들고, 그 문자가 텍스트에 나온 횟수를 가중치로 삼는다.
- 위에서 만든 트리 개를 담은 집합 를 만든다.
- 에 트리가 둘 이상 있는 동안 다음을 반복한다.
- 가중치가 가장 작은 트리 를 골라 에서 뺀다.
- 가중치가 가장 작은 트리 를 골라 에서 뺀다.
- 을 왼쪽 서브트리, 를 오른쪽 서브트리로 하는 새 트리 를 만들고, 과 의 가중치 합을 의 가중치로 삼는다.
- 를 에 넣는다.
- 에 남은 하나뿐인 트리를 반환한다.
3의 1번과 2번 단계에서 가중치가 가장 작은 트리가 여러 개일 수 있으므로, 텍스트가 같아도 트리 모양은 하나로 정해지지 않는다. 텍스트 abracadabra에서 a는 5번, b와 r은 각각 2번, c와 d는 각각 1번 나온다. 어떤 실행은 a, b, r, c, d의 부호 길이를 1, 2, 3, 4, 4로 만들고, 다른 실행은 1, 3, 3, 3, 3으로 만든다.
문자의 부호는 완성된 트리에서 루트부터 그 문자에 해당하는 잎까지 가는 경로로 정해진다. 부호의 길이는 그 경로에 있는 간선의 수이고, 경로에 있는 내부 노드의 수와 같다.
알고리즘이 고른 부호 개의 길이가 주어진다. 만들어진 부호의 길이가 정확히 그 길이가 되게 하는 텍스트 중에서 가장 작은 크기, 즉 전체 문자 수의 최솟값을 구하라.
입력
첫째 줄에 텍스트에 나오는 서로 다른 문자의 수를 뜻하는 정수 이 주어진다. ()
둘째 줄에 알고리즘이 각 문자에 고른 부호의 길이 가 개 주어진다. (, )
위에서 설명한 방법으로 만들 수 있는 트리 중에서 주어진 길이의 부호를 만드는 트리가 적어도 하나 있다.
출력
만들어진 부호의 길이가 주어진 길이가 되게 하는 텍스트의 가장 작은 크기, 즉 전체 문자 수의 최솟값을 정수 하나로 한 줄에 출력한다.