<----my github

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;
}
posted @ 2022-01-03 20:33  CinqueOrigin  阅读(79)  评论(0)    收藏  举报