POJ3253 Fence Repair (贪心)

题目链接http://poj.org/problem?id=3253

 

题目大意:FJ为了修理栅栏,要将一块很长的木板切成n块,切割前后木板的总长度不变,每次切割要花费的代价是切割以后两块木板的长度,求付出的最小花费代价。

思路:解题思想类似于哈夫曼树,让需要的最短的木板的节点深度最深。由题意可知,每次切割花费的代价是切割后两块木板的长度,所以要使得花费代价最少,只需使得需要的n块木板中最长的木板切割的次数最少,所以每次要选择当前木板中长度最小的两个。

 

AC代码如下:

 

#include <cstdio>
#include <cstring>
#include <algorithm>
#define ll long long
using namespace std;

const int maxn = 20005;
int a[maxn],n; 

int main(){
	while(~scanf("%d",&n)){
		ll ans = 0, sum = 0,t;
		for(int i = 0; i < n; i ++){
			scanf("%d",&a[i]);
		}
		
		while(n > 1){
			int last = 1,first = 0;
			if(a[first] > a[last]) swap(first,last);
			for(int i = 2; i < n; i ++){
				if(a[i] < a[first])
					last = first,first = i;
				else if(a[i] < a[last])
					last = i;
			}
			ll t = a[first] + a[last];
			ans += t;
			if(first == n-1) swap(first,last);
			a[first] = t;	a[last] = a[n-1];//每循环一次,n-1下标处的元素都会丢失 
			n --;
		}
		printf("%lld\n",ans);
	}
	return 0;
}

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值