Fence Repair-栅栏维修POJ 3253
农夫约翰想要修复牧场周围的一小段围栏。他测量围栏,并发现他需要Ñ(1≤ Ñ ≤20000)厚木板,每一个都具有一些整数长度大号我(1≤大号我≤50000)单元。然后,他购买了单个长板刚好足够长以锯入Ñ木板(即,其长度为所述长度之和大号我)。FJ 忽略了“切口”,即在进行锯切时因锯屑而损失的额外长度;你也应该忽略它。
FJ 悲伤地意识到他没有用来切割木头的锯子,所以他拿着这块长木板去农夫唐的农场,礼貌地问他是否可以借一把锯子。
Farmer Don 是壁橱资本家,并没有借给 FJ 一把锯子,而是提出向 Farmer John 收取每N -1 块木板切割的费用。切割一块木头的费用正好等于它的长度。切割一块长度为 21 的木板需要 21 美分。
Farmer Don 然后让 Farmer John 决定切割木板的顺序和位置。帮助农民约翰确定他可以花费的最低金额来制作N 块木板。FJ 知道他可以按各种不同的顺序切割木板,这将导致不同的费用,因为由此产生的中间木板长度不同。
输入
第 1 行:一个整数
N,木板的数量
第 2 行.. N +1:每行包含一个整数,描述所需木板的长度
第 2 行.. N +1:每行包含一个整数,描述所需木板的长度
输出
第 1 行:一个整数:他必须花费的最少金额才能进行
N -1 次削减
样本输入
3
8
5
8
8
样本输出
34
题意描述:
给你几个数代表我们要得到的木板长度,这些数的总长度是木板最开始的长度,我们有不同的方案可以得到木板长度,每次切割木板都要花费和隔断的两个木板长度相同的价钱,求得到我们要的木板长度需要花费的最小价钱
解题思路:
利用了优先队列,先把要的到的木板长度从小到大排序,然后都放到队列里面,然后把里面的值两两相加,把旧数据弹出,新数据放进去,一直到队列里面只有一个值的时候输出,就是我们要的答案,输出即可
易错分析:
本题数据较大,所以记录和的时候int会溢出,要定义为longlong型
AC代码
#include<stdio.h> #include<queue> #include<iostream> using namespace std; int main() { int n,m,a,b; long long sum; while(~scanf("%d",&n)) { priority_queue<int,vector<int>, greater<int> >Q; for(int i=1;i<=n;i++) { scanf("%d",&m); Q.push(m); } sum=0; while(Q.size()>1) { a=Q.top(); Q.pop(); b=Q.top(); Q.pop(); Q.push(a+b); sum+=a+b; } printf("%lld\n",sum); } return 0; }