最优二叉树解决Fruit问题

最优二叉树的思想可以应用在很多方面,下面就是一个例子:

/*
Description
“What an amazing garden!” Tiantian exclaimed. When she walks in the garden, she finds that fruit falls and automatically forms a line! “Maybe you can be superwoman after eating all the fruit” Tiantian said to herself. So an idea came to her! She would like to pile the fruit together and move them away. But as a girl, it’s so hard for her to move more than one pile once, so she would like to merge two piles of fruit together once a time. And to make the work smoothly, she wants to do it with the least cost, can you help her?

Each pile of fruit has a weight. If there are two piles of fruit, their weights are a and b,then merging this two piles of fruit together will cost a+b, and the weight of the new fruit pile is a+b.

Input

The input contains several test cases. Each test case starts with a line containing an integer N (1<=N<=10000), which describes the number of the piles of fruit in the garden. And then N integers follow in the next line, separated by a space, to describe the N weight of the N piles of fruit. All of them is an integer no larger than 20000.

Output

For each test case, output only one line of an integer, to tell the least cost for Tiantian to pay. It’s sure that the result will be no more than 2147483647.

Sample Input

3
1 2 9

Sample Output

15

Hint
First, Tiantian piles the first two piles of fruit together, and cost 1+2=3, and they form a new pile of fruit weights 3. Then Tiantian piles the left two piles of fruit together, and cost 3+9=12. So the total cost is 3+12=15.
*/

 

题目的意思很明显,就是有一堆数字,先取出最小的两个数,相加组成一个新的数加到原来的数组中,依次类推,直到只剩下一个数,就是我们要求的值。

这就符合了最优二叉树的思想:先取两个权值最小的节点,构造出的父节点加到其他节点中去,依次类推,实现构造一棵树。只要把所有节点的权值相加,就是我们所要的结果。

这里面唯一一个问题是一个数组如何取最小值,如果用遍历的方法,取出所有的数的时间复杂度无疑是O(n^n)。我是使用优先队列的方法,这样就把时间复杂度降低到o(nlgn),没什么难度,代码如下:

#include<iostream>
#include<fstream>
#include<string>
#include<vector>
#include<queue>
using namespace std;

struct cmp
{
	bool operator()(int x,int y)
	{
		return (x>y);
	}
};

int main()
{
	int n;
	while(cin>>n)
	{
		int total=0;
		priority_queue<int,vector<int>,cmp> data;
		for(int i=0;i<n;i++)
		{
			int tmp;
			cin>>tmp;
			data.push(tmp);
		}//end of n

		//判断只有一个元素的时候
		if(data.size()==1)
		{
			cout<<data.top()<<endl;
			continue;
		}

		//用优先队列取出最小的两个
		while(!data.empty())
		{
			int tmp1,tmp2;
			tmp1=data.top();
			data.pop();
			tmp2=data.top();
			data.pop();
			total+=tmp1+tmp2;
			if(!data.empty())
				data.push(tmp1+tmp2);
		}//end of while
		cout<<total<<endl;
	}//end or while
}


 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值