POJ 3253 Fence Repair 栅栏维修
题目的链接在这里。
设把一块长为a+b的木板切割为一块a的木板和一块长为b的木板,那么费用是a+b,很明显,这里要求的是哈弗曼树,每个最终要的木块是一个叶子节点,其权重是其长度,两个子节点可以合并为一个父节点,
父节点的权重是两个子节点长度的和。
具体的求解代码如下:
点击查看代码
#include<iostream>
#include<algorithm>
using namespace std;
/*
*将每个目标木块看作一个叶子结点
* 每两个结点可以生成一个父节点,父节点的权重等于两个孩子结点的权重合,那么这个父节点可以看作两个子木块劈开前的父木块
* 所以只需要求这些结点的哈弗曼树即可
*/
int scrap[40000];
void insert(int num,int begin, int end) {
int temp = end;
int mid;
while (begin <= end) {
mid = (begin + end) / 2;
if (num < scrap[mid]) end = mid - 1;
else begin = mid + 1;
}
for (int j = temp; j >= begin; j--) {
scrap[j + 1] = scrap[j];
}
scrap[begin] = num;
}
int main() {
long long sum = 0;
int temp1, temp2, temp3;
int N;
cin >> N;
int i = 0;
while (i<N) {
cin >> scrap[i++];
}
sort(scrap, scrap + N);
int begin = 0, end = N-1;
while (begin < end) {
//选出两个最小的元素,删除这两个元素
temp1 = scrap[begin];
temp2 = scrap[begin + 1];
begin += 2;
//合并成一个元素
temp3 = temp1 + temp2;
sum += temp3;
//将新元素插入
insert(temp3, begin, end);
end++;
}
cout << sum;
return 0;
}
本文来自博客园,作者:CinqueOrigin,转载请注明原文链接:https://www.cnblogs.com/CinqueOrigin/p/15760442.html

浙公网安备 33010602011771号