题面
题意
一开始有一个数,每次可以将一个数分成2或3组,并分别放入一组,代价为这n个数的大小,使最后有n组,并给出每组的数字大小
方法
可以看作将n个数合并,每次可以合并2个或3个,代价为几个数的和,最后合并成一个数.
从贪心的角度来看,3个3个合并最优,因为每次可以减少两个数,事实上在奇数个数时确实如此,有偶数个数时,因为最后只剩下了两个数,代价不是最小的,故可以先加一项0,再当奇数个数来处理.
上述方法可以用堆来实现,每次合并最小的三个数.
注意,n为1时要特判,答案为0.
代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;
priority_queue<ll,vector<ll>,greater<ll> >pq;
ll n,ans,tmp;
int main()
{
ll i,j,p;
cin>>n;
for(i=1;i<=n;i++)
{
scanf("%lld",&p);
pq.push(p);
}
if(n==1)
{
cout<<0;
return 0;
}
if(n%2==0) pq.push(0);
while(pq.size()>3)
{
tmp=pq.top();
pq.pop();
tmp+=pq.top();
pq.pop();
tmp+=pq.top();
pq.pop();
ans+=tmp;
pq.push(tmp);
}
// cout<<pq.empty();
while(!pq.empty())
{
ans+=pq.top();
pq.pop();
}
printf("%lld",ans);
}