7-1 修理牧场 (25 分)(最详解)(最容易理解的解题过程)
农夫要修理牧场的一段栅栏,他测量了栅栏,发现需要N块木头,每块木头长度为整数Li个长度单位,于是他购买了一条很长的、能锯成N块的木头,即该木头的长度是Li的总和。
但是农夫自己没有锯子,请人锯木的酬金跟这段木头的长度成正比。为简单起见,不妨就设酬金等于所锯木头的长度。例如,要将长度为20的木头锯成长度为8、7和5的三段,第一次锯木头花费20,将木头锯成12和8;第二次锯木头花费12,将长度为12的木头锯成7和5,总花费为32。如果第一次将木头锯成15和5,则第二次锯木头花费15,总花费为35(大于32)。
请编写程序帮助农夫计算将木头锯成N块的最少花费。
输入格式:
输入首先给出正整数N(≤104),表示要将木头锯成N块。第二行给出N个正整数(≤50),表示每段木块的长度。
输出格式:
输出一个整数,即将木头锯成N块的最少花费。
输入样例:
8
4 5 1 2 1 3 1 1
输出样例:
49
题目解释:利用建造哈夫曼树的思想 根据叶节点的权值 排序(升序)(模仿最小堆) 将其所有叶节点的权值入队 当然我们入的是C++中的优先队列(模仿最小堆)
分享C++中 被调用的 优先队列类及其方法
优先队列具有队列的所有特性,包括基本操作,只是在这基础上添加了内部的一个排序,它本质是一个堆实现的
和队列基本操作相同:
top 访问队头元素
empty 队列是否为空
size 返回队列内元素个数
push 插入元素到队尾 (并排序)
emplace 原地构造一个元素并插入队列
pop 弹出队头元素
swap 交换内容
定义:priority_queue<Type, Container, Functional>
Type 就是数据类型,Container 就是容器类型(Container必须是用数组实现的容器,比如vector,deque等等,但不能用 list。STL里面默认用的是vector),Functional 就是比较的方式,当需要用自定义的数据类型时才需要传入这三个参数,使用基本数据类型时,只需要传入数据类型,默认是大顶堆
一般是:
//升序队列
priority_queue <int,vector<int>,greater<int> > q;
//降序队列
priority_queue <int,vector<int>,less<int> >q;
//哈夫曼树
#include<bits/stdc++.h>
using namespace std;
int main(){priority_queue <int,vector<int>,greater<int> > q;//优先队列 中 升序队列int N,i,j,k,a[10000],d[10000],sum=0;scanf("%d",&N);for(i=0;i<N;i++){scanf("%d",&a[i]);}for(i=0;i<N;i++){q.push(a[i]);}while(!q.empty()&&q.size()!=1){int temp1= q.top();//先访问 再弹出 q.pop();int temp2= q.top();q.pop();int temp=temp1+temp2;sum+=temp;q.push(temp);} printf("%d",sum);
}