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 }
浙公网安备 33010602011771号