Heap & 우선순위 큐
카드 정렬하기
4gats
2024. 2. 11. 17:14
https://www.acmicpc.net/problem/1715
1715번: 카드 정렬하기
정렬된 두 묶음의 숫자 카드가 있다고 하자. 각 묶음의 카드의 수를 A, B라 하면 보통 두 묶음을 합쳐서 하나로 만드는 데에는 A+B 번의 비교를 해야 한다. 이를테면, 20장의 숫자 카드 묶음과 30장
www.acmicpc.net
카드의 장수가 적은 카드 묶음끼리
더하는 것이 횟수를 줄일 수 있다.
10, 20, 40이 있으면
10, 20을 합치고
30, 40을 하면 -> 100회
즉, 현재 존재하는 카드 묶음 중에서
가장 적은 2개의 묶음을 우선적으로 계산
-> 우선 순위 큐
<우선순위 큐 구현>
배열을 이용한 이진트리로 구현한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
|
#include <iostream>
#include <queue>
using namespace std;
int genzai;
int arr[100'004];
int Heap[100'004];
// 최소 힙
void Heap_push(int data)
{
int idx = ++genzai;
Heap[idx] = data;
while ((idx != 1) && (data < Heap[idx / 2]))
{
swap(Heap[idx], Heap[idx / 2]);
idx = idx / 2;
}
}
int Heap_pop()
{
// 완전 이진 트리 -> 1부터 시작
int result = Heap[1];
// 제일 마지막을 위로 올리고
// Top-down
Heap[1] = Heap[genzai];
genzai--;
int parent = 1;
int child;
while(true)
{
child = parent * 2;
// 자식노드 두 개 중 작은 값을 선택
if (child + 1 <= genzai && Heap[child + 1] < Heap[child])
child++;
// 부모가 자식보다 작으면 끝
if (child > genzai || Heap[parent] < Heap[child])
break;
swap(Heap[child], Heap[parent]);
parent = child;
}
return result;
}
int main()
{
int n;
cin >> n;
for (int i = 0; i < n; i++)
cin >> arr[i];
int ans = 0;
int cmp_cnt = n - 1;
for (int i = 0; i < n; i++)
Heap_push(arr[i]);
for (int i = 0; i < cmp_cnt; i++)
{
int n1 = Heap_pop();
int n2 = Heap_pop();
ans += (n1 + n2);
Heap_push(n1 + n2);
}
cout << ans << '\n';
return 0;
}
|
cs |
<STL>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
#include <iostream>
#include <queue>
using namespace std;
int arr[100004];
int main()
{
int n;
cin >> n;
for (int i = 0; i < n; i++)
cin >> arr[i];
//priority_queue<int> pq;
// 최소 힙
priority_queue<int, vector<int>, greater<int>> pq;
int ans = 0;
int cmp_cnt = 0;
for (int i = 0; i < n; i++)
pq.push(arr[i]);
// pq.push(-arr[i]) 이렇게도 할 수 있다.
while (!pq.empty())
{
if (cmp_cnt == n - 1)
break;
int num1 = pq.top();
pq.pop();
int num2 = pq.top();
pq.pop();
ans += (num1 + num2);
pq.push(num1 + num2);
cmp_cnt++;
}
cout << ans << '\n';
return 0;
}
|
cs |