【CF884D】Boxes And Balls k叉哈夫曼树

题目大意:给定一个大小为 N 的集合,每次可以从中挑出 2 个或 3 个数进行合并,合并的代价是几个数的权值和,求将这些数合并成 1 个的最小代价是多少。

引理:K 叉哈夫曼树需要保证 \((n-1)\%(k-1)=0\),在此基础上,每次取 K 个合并即可得到最小代价。

代码如下

#include <bits/stdc++.h>
using namespace std;

inline int read(){
	int x=0,f=1;char ch;
	do{ch=getchar();if(ch=='-')f=-1;}while(!isdigit(ch));
	do{x=x*10+ch-'0';ch=getchar();}while(isdigit(ch));
	return f*x;
}

int n;
long long ans,tmp;
priority_queue<long long,vector<long long>,greater<long long> >q;

void solve(){
	n=read();
	for(int i=1;i<=n;i++)q.push(read());
	if(!(n&1))q.push(0),n++;
	for(int i=n;i^1;i-=2)tmp=q.top(),q.pop(),tmp+=q.top(),q.pop(),tmp+=q.top(),q.pop(),q.push(tmp),ans+=tmp;
	printf("%lld\n",ans);
}

int main(){
	solve();
	return 0;
}
posted @ 2018-12-06 16:55  shellpicker  阅读(234)  评论(0编辑  收藏  举报