Boxes And Balls(三叉哈夫曼编码)

题目

原题链接:http://codeforces.com/problemset/problem/884/D

现有一堆小石子,要求按要求的数目分成N堆,分别为a1、a2、...an。具体的,每次选一个堆(其重量为代价),分成2或3堆。求最小的可能代价。

思路

我们反向考虑,就是一个不断合并的过程。当n为奇数,我们总能找到三个最小的合并,直到只剩一堆;当n为偶数,先选择最小的两个合并,再按奇数一样处理。(为了统一起来,添加一个辅助堆,石子个数为0)

代码实现

 1 #include<stdio.h>
 2 #include<iostream>
 3 #include<queue>
 4 using namespace std;
 5 
 6 typedef long long ll;
 7 int n;
 8 
 9 int main()
10 {
11     while (scanf("%d",&n) == 1)
12     {
13         priority_queue<ll,vector<ll>,greater<ll> >q;
14         ll ans = 0;
15         for (int i = 0; i < n; i++)
16         {
17             int tmp;
18             scanf("%d", &tmp);
19             q.push(tmp);
20         }
21         if ((n & 1) == 0)  q.push(0);  //n为偶数,补充一个0
22         while (q.size() > 1)
23         {
24             ll a = q.top(); q.pop();
25             ll b = q.top(); q.pop();
26             ll c = q.top(); q.pop();
27             ans += (a + b + c);
28             q.push(a + b + c);
29         }
30         q.pop();
31         printf("%I64d\n", ans);
32     }
33 }

参考链接:

http://codeforces.com/blog/entry/55470

http://www.cplusplus.com/reference/queue/priority_queue/

 

posted @ 2018-10-12 17:08  Rogn  阅读(517)  评论(0编辑  收藏  举报