POJ 3253 Fence Repair 柵欄維修
阿新 • • 發佈:2022-01-03
題目的連結在這裡。
設把一塊長為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; }