题目链接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;
}