給定 N 個正整數(2 ≤ N ≤ 5000),每次選兩個數相加,成本為兩數之和,將結果放回集合。重複直到剩一個數。求最小總成本。輸入以 N=0 結束。
這是經典的霍夫曼編碼 / 最優合併模式問題。每次取出最小的兩個數相加,將和累加到總成本,並將和放回集合。使用最小堆(優先隊列)可在 O(N log N) 完成。若每次排序則為 O(N² log N),對 N=5000 可能超時。
範例:1 2 3 → 先加 1+2=3(成本 3),再加 3+3=6(成本 6),總成本 9,為最小。
#include <bits/stdc++.h>
using namespace std;
int main() {
int n;
while (cin >> n, n) {
priority_queue<long long, vector<long long>, greater<long long>> pq;
for (int i = 0, x; i < n; i++) {
cin >> x;
pq.push(x);
}
long long total = 0;
while (pq.size() > 1) {
long long a = pq.top(); pq.pop();
long long b = pq.top(); pq.pop();
long long sum = a + b;
total += sum;
pq.push(sum);
}
cout << total << '\n';
}
return 0;
}
原文提供的代碼使用每次排序的方式(sort(num+cnt, num+n)),雖然邏輯正確,但時間複雜度較高。建議改用優先隊列以通過大數據測試。