【POJ3253】Fence Repair(合并果子的翻版)

题面:【POJ3253】Fence Repair

考虑到每一次切割所花费的代价是所切割的木板的长度,那我们就可以反向思考,合并两块木板所花费的代价是这两块木板的长度和,那么问题就转化为了将输入中给出的N块木板给两两合并在一起。于是,我们会惊奇地发现这道题其实就是合并果子的翻版,一道用小根堆来优化的贪心题!

当然了,手打堆是比较麻烦的,相比之下,C++自带的优先队列就好用多了。代码见下:

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cmath>
#include<queue>
#define max(x,y) (x>y?x:y)
#define min(x,y) (x<y?x:y)
#define LL long long
#define N 20000
using namespace std;
int n,a[N+5];
priority_queue<int,vector<int>,greater<int> > q;//建立一个小根堆 
int read()//读优 
{
	int x=0,f=1;char ch=getchar();
	while((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
	if(ch=='-') f=-1,ch=getchar();
	while(ch>='0'&&ch<='9') (x*=10)+=ch-'0',ch=getchar();
	return x*=f;
}
void write(LL x)//输优 
{
	if(x<0) putchar('-'),x=-x;
	if(x>9) write(x/10);
	putchar(x%10+'0');
}
int main()
{
	n=read();
	for(int i=1;i<=n;i++) a[i]=read(),q.push(a[i]);//边读入边将数字放入堆中(当然,这题其实完全不需要开数组,可以直接用临时变量来读入)
	LL ans=0;//答案要用long long存储 
	for(int i=1;i<n;i++) {int x=q.top();q.pop(),ans+=(x+=q.top()),q.pop(),q.push(x);}//每次取出堆顶的两个数,将ans加上这两个数之和,并记得将这两个数之和重新放入堆中, 
	write(ans);
	return 0;
}



版权声明:转载请注明地址


猜你喜欢

转载自blog.csdn.net/chenxiaoran666/article/details/79939470