洛谷地址:https://www.luogu.org/problemnew/show/P1090

白书第五版:448页

【 P1090 合并果子】堆模解题/queue优先队列解题/哈夫曼树模板题/贪心求解未完善

【 P1090 合并果子】堆模解题/queue优先队列解题/哈夫曼树模板题/贪心求解未完善

(1)分析图

【 P1090 合并果子】堆模解题/queue优先队列解题/哈夫曼树模板题/贪心求解未完善 

堆策略:3+12=15   为最小合并力气

#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
int heap_size,n;
int heap[30001];

void put(int d)
{  //入堆, 完全二叉树最后一个元素入堆后并维护堆 
    int now,next;
    heap[++heap_size]=d;
    now=heap_size;
    while(now>1)
     {   next=now/2;   //next是父节点 
         if(heap[now]>=heap[next]) break;    //小根堆
        swap(heap[now],heap[next]);
        now=next;     
     } 
}

int  get( )
{  //出堆 
    int now,next,res;
    res=heap[1]; //第一个出堆 
    heap[1]= heap[heap_size--]; //最后面一个调整到第一个
    now=1;
    while(now*2<=heap_size)
     { next=now*2;
       if(next<heap_size&&heap[next+1]<heap[next]) next++; //next标记最小的
       if(heap[now]<=heap[next])  break; //维护小根堆
       else swap(heap[now],heap[next]);
       now=next; 
     }
     return res;  //弹出堆顶
}
void  work()
{
    int i,x,y,ans=0;
    cin>>n;
    for(i=1;i<=n;i++)
     {cin>>x; put(x);}  //输入的元素入堆,建立小根堆
     
     for(i=1;i<n;i++)  // n个数 合并n-1次 
       {                      
           x=get();  y=get();      //i=1   x=1,y=2 ans=3   3入堆 
           ans+=x+y;               //i=2   x=3,y=9 ans=3+3+9=15  15入堆,结束循环 
           put(x+y);
        }  
     cout<<ans<<endl;
}
int main()
{
    work();
    return 0;
 } 
View Code

相关文章: