SJTU合并果子

【问题描述】

现在有N堆果子,要把他们合并为一堆。每次合并只能合并其中的两堆,假如要合并的两堆果子分别有a颗果子和b颗果子,那么合并这两堆果子需要消耗a+b点体力。问合并完所有果子需要最小的体力数是多少。
【输入形式】

共两行。

第一行为一个正整数N<=1000。表示果子总共有多少堆。

第二行共N个正整数,ai表示第i堆果子的数目。
【输出形式】

一个正整数,表示消耗的最小体力数。
【样例输入】

5
1 2 3 4 5

【样例输出】

33

【样例说明】

合并1,2消耗体力3,产生一个大小为3的果子堆。

合并4,5消耗体力9,产生一个大小为9的果子堆。

合并3,3消耗体力6,产生一个大小为6的果子堆。

合并6,9消耗体力15,产生一个大小为15的果子堆。

共消耗体力33.

优先级队列头文件

#pragma once

template < class T>
class priorityQueue {
public:
	priorityQueue(int capacity = 100); 
	priorityQueue(const T data[], int size);
	~priorityQueue(); 
	bool isEmpty() const;
	void enQueue(const T & x); 
	T deQueue(); 
	T getHead() const; 
	int size() const { return currentSize; }
	int findMin(T x) {     // 找出大于等于x的最小元素
		T Min; 
		int ID = -1;
		for(int i = 1; i <= currentSize; ++i)
			if (array[i] >= x && (Min == -1 || array[i] < Min)) {
				Min = array[i];
				ID = i;
			}
	return ID; 
	}
	void decreaseKey(int i, T value) {  // 将堆中第i个结点的值减少value
	T x;
	int hole;
	array[hole = i] -= value;      // 将第i个元素减少value
	for(x = array[i]; hole>1 && x < array[hole/2]; hole /= 2)//过滤
		array[hole] = array[hole / 2];
	array[hole] = x;
	}
private:
	int currentSize;
	T *array;
    int maxSize;
	void doubleSpace() ;
	void buildHeap() ;
	void percolateDown(int hole); //向下过滤
};

template < class T>
priorityQueue<T>::priorityQueue(int capacity)
{
	array = new T[capacity];
	maxSize = capacity;
	currentSize = 0;
}

template < class T>
priorityQueue<T>::priorityQueue(const T* items, int size) :maxSize(size + 10), currentSize(size)
{
	array = new T[maxSize];
	for (int i = 0; i <= currentSize; ++i)
		array[i] = items[i];
	buildHeap();
}

template < class T>
priorityQueue<T>::~priorityQueue()
{
	delete[]array;
}

template < class T>
bool priorityQueue<T>::isEmpty()const
{
	return currentSize == 0;
}

template < class T>
T priorityQueue<T>::getHead()const
{
	return array[1];
}

template < class T>
void priorityQueue<T>::enQueue(const T& x)
{
	if (currentSize == maxSize - 1) doubleSpace();
	int hole = ++currentSize;
	for (; hole > 1 && x < array[hole / 2]; hole /= 2)
		array[hole] = array[hole / 2];
	array[hole] = x;
}

template < class T>
void priorityQueue<T>::doubleSpace()
{
	T* tmp = array;
	maxSize *= 2;
	array = new T[maxSize];
	for (int i = 0; i <= currentSize; ++i)
		array[i] = tmp[i];
	delete[]tmp;
}

template < class T>
T priorityQueue<T>::deQueue()
{
	T minItem;
	minItem = array[1];
	array[1] = array[currentSize--];
	percolateDown(1);
	return minItem;
}

template < class T>
void priorityQueue<T>::percolateDown(int hole)
{
	int child;
	T tmp = array[hole];
	for (; hole * 2 <= currentSize; hole = child)
	{
		child = hole * 2;
		if (child != currentSize && array[child + 1] < array[child])
			child++;
		if (array[child] < tmp) array[hole] = array[child];
		else break;
	}
	array[hole] = tmp;
}

template < class T>
void priorityQueue<T>::buildHeap()
{
	for (int i = currentSize / 2; i > 0; i--)
		percolateDown(i);
}

cpp文件:

#include 
#include "priorityQueue.h"
using namespace std;

int main()
{
	int n, num;
	priorityQueue<int> q;
	cin >> n;
	for (int i = 0; i < n; i++)
	{
		cin >> num;
		q.enQueue(num);
	}
	int ans = 0, a, b;
	while (q.size() > 1)
	{
		a = q.deQueue();
		b = q.deQueue();
		ans += a + b;
		q.enQueue(a + b);
	}
	cout << ans << endl;
	return 0;
}

吐槽:本道题是作业题,课程进度还没到优先级队列,所以老师期待的做法应该不是用优先级队列实现哈夫曼;但是……我不会其他的,如果有其他优秀做法欢迎留言!!

你可能感兴趣的:(数据结构sjtu)