codeforces 884D 哈夫曼编码

传送门http://codeforces.com/contest/884/problem/D

题意:

  在1号盒子里有n种颜色的球,每种颜色ai个,要将第i种颜色的球放置到第i个盒子里。每次可以将一个盒子的所有的球拿出,分成2-3份,代价是这个盒子球的总个数,求最小的花费。

题解:

  如果只能分成两份,将这个过程反过来,其实就是哈夫曼编码,现在还可以分成3份,那么就应该是三叉的哈夫曼编码,类比着二叉哈夫曼编码搞一个三叉的就可以了。但是三叉的哈夫曼编码存在一个问题,有时可能因为节点个数不够存在而变成二叉。我们想一想就可以知道当二叉节点越靠下那么带权的路径长度越小。

  什么时候会出现二叉哪,想一想就可以知道是叶子结点有偶数个的时候就会出现二叉,所以加个0就可以把存在二叉变成全三叉了。

 

 1 #include <bits/stdc++.h>
 2 #define eps 1e-10;
 3 #define INF 0x3f3f3f3f
 4 using namespace std;
 5 typedef long long LL;
 6 typedef unsigned long long ULL;
 7 const int maxn=2e5+100;
 8 LL n,x,ans;
 9 priority_queue<LL,vector<LL>,greater<LL>> q;
10 int main() {
11     #ifdef ac
12         freopen("in.txt","r",stdin);
13         //freopen("out.txt","w",stdout);
14     #endif // ac
15     cin >> n;
16     for(int i=1;i<=n;++i) cin >> x,q.push(x);
17     if(!(n&1)) q.push(0);
18     while(q.size()>1) {
19         LL tmp=q.top(); q.pop();
20         tmp+=q.top(); q.pop();
21         tmp+=q.top(); q.pop();
22         ans+=tmp; q.push(tmp);
23     }
24     cout << ans << endl;
25     return 0;
26 }

 

posted on 2017-12-23 12:33  KKaly  阅读(384)  评论(0)    收藏  举报

导航