POJ 3253 Fence Repair 优先队列

看题传送门::http://poj.org/problem?id=3253


题目大意:

给定n个小木板的长度,一个农夫要把一个无限长的木板锯成给定的目标,每一次锯的长度就是费用,求最小费用。

hints:

目标长度为:8 5 8

起初的木板长度为8+5+8=21

第一切将会花费21 ,将 切为13 和 8 两块。

第二次将会花费13 ,将13那块切为 8 和 5 两块。


贪心算法。

一开始想错,以为每次切掉最长的,其实不然,没有理解题意。

其实题目说的是每次切掉部分的两块的和才为费用。

dicuss里有大神的关于Huffman树的思路“

我们不妨将切木板的过程反过来看,也就是将所有切好了的木板每次拿两块拼接起来(每次拼接后的长度就是费用),最终便会拼接成原来的完整的木板。显然,这个过程是Huffman编码过程,且正过程和逆过程费用相同”

所以利用这个思想,每次选取最短的两个木板,构成新的木板,并重新插入优先队列中。

用到了STL的优先队列

#include<cstdio>
#include<queue>
using namespace std;
const int MAXN=50000+10;
struct data
{
	__int64 need;

	bool operator <(const data& p)const
	{
		return need > p.need;
	}
};


priority_queue<data> q;
int main()
{
	int n;
	while(scanf("%d",&n)!=EOF)
	{
		data s;
		for(int i=0;i<n;i++)
		{
			scanf("%I64d",&s.need);
			q.push(s);
		}
		__int64 ans=0;
		while(q.size()>1 )
		{
			int k1=q.top().need;
			q.pop();
			int k2=q.top().need;
			q.pop();
			data temp;
			temp.need=k1+k2;
			ans+=temp.need;
			q.push(temp);

		}
		printf("%I64d\n",ans);

		while(!q.empty())  //清空队列  
			q.pop();  
	}
}


你可能感兴趣的:(POJ 3253 Fence Repair 优先队列)