luoguP2168 [NOI2015]荷马史诗 哈夫曼树
如果不会哈夫曼树理论的话这题很难做出来吧...
如果 K=2,就可以根据合并果子那样去构造.
然后 K>2 的话就构造 k 叉哈夫曼树,如果不满足 $(n-1) \% (k-1)$ 的话就自动补一些进去.
code:
#include <bits/stdc++.h>
#define ll long long
#define N 100008
#define setIO(s) freopen(s".in","r",stdin)
using namespace std;
int n,k;
ll a[N];
struct data {
ll w,h;
data(ll w=0,ll h=0):w(w),h(h){}
bool operator<(const data b) const
{
return w==b.w?h>b.h:w>b.w;
}
};
priority_queue<data>q;
int main()
{
// setIO("input");
int x,y,z,det=0;
scanf("%d%d",&n,&k);
for(int i=1;i<=n;++i) scanf("%lld",&a[i]),q.push(data(a[i],1));
if((n-1)%(k-1)) det=k-1-(n-1)%(k-1); // 补的节点
for(int i=1;i<=det;++i) q.push(data(0,1));
det+=n;
ll ans=0;
while(det>1)
{
ll tmp=0,maxh=0;
for(int i=1;i<=k;++i)
tmp+=q.top().w,maxh=max(maxh,q.top().h),q.pop();
ans+=tmp;
q.push(data(tmp,maxh+1));
det-=k-1;
}
printf("%lld\n%lld\n",ans,q.top().h-1);
return 0;
}

浙公网安备 33010602011771号