【BZOJ】1724 [Usaco2006 Nov]Fence Repair 切割木板

时间:2023-03-09 08:29:48
【BZOJ】1724 [Usaco2006 Nov]Fence Repair 切割木板

【算法】贪心+堆

#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=;
int n,heap[maxn],sz;
void heap_push(int x)
{
heap[++sz]=x;//新数入堆底
int now=sz;//以堆底为起点
while(now>&&heap[now]<heap[now>>])//非根节点的父亲>儿子时------注意非根判断
{
swap(heap[now],heap[now>>]);//交换即上推
now>>=;//转移到父亲
}
}
int heap_pop()
{
int ans=heap[];//取出答案
heap[]=heap[sz--];//将堆底最后一个元素调上来
int now=;//以堆顶为起点
while(now<=(sz>>))//若now有儿子------儿子存在判断
{
int next=now<<;//令next为now的左儿子------儿子赋变量
if(next<sz&&heap[next]>heap[next|])next++;//now有右儿子且右儿子更小时,令next为右儿子------左右儿子判断---注意右儿子存在判断
if(heap[next]>heap[now])return ans;//若根比儿子小,满足条件,退出
else
{
swap(heap[now],heap[next]);//交换即下推
now=next;//转移到儿子
}
}
return ans;
}
int main()
{
scanf("%d",&n);
for(int i=;i<=n;i++)
{
int u;
scanf("%d",&u);
heap_push(u);
}
long long ans=;
for(int i=;i<n;i++)
{
int u=heap_pop(),v=heap_pop();
heap_push(u+v);
ans+=u+v;
}
printf("%lld",ans);
return ;
}