1. 程式人生 > 其它 >POJ 3253 Fence Repair 柵欄維修

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;
}