首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> C++ 入門

UVA 10954 Add All 貪心算法:最小堆優化實現詳解

     編輯:C++ 入門

UVA 10954 Add All - 貪心策略與優先隊列實現

題目要求反覆取出兩個最小數相加,將和放回,直到剩一個數。所有相加過程中產生的和的總和即為答案。這是經典的霍夫曼編碼/最優合併模式問題,貪心策略:每次合併最小的兩個數,總代價最小。

算法證明直觀理解

類比霍夫曼樹構建:將每個數視為葉子節點權重,每次合併對應創建父節點。越小的權重越早參與合併,累加的層數越多,對總代價貢獻越大。因此優先合併最小的兩個數能得到全局最優解。

優先隊列 (最小堆) 優化實現

#include 
#include 
using namespace std;

int main() {
    long long n, x;
    while (scanf("%lld", &n) != EOF && n) {
        priority_queue, greater> pq;
        for (int i = 0; i < n; i++) {
            scanf("%lld", &x);
            pq.push(x);
        }
        long long ans = 0;
        while (pq.size() > 1) {
            long long a = pq.top(); pq.pop();
            long long b = pq.top(); pq.pop();
            long long sum = a + b;
            ans += sum;
            pq.push(sum);
        }
        printf("%lld\n", ans);
    }
    return 0;
}

複雜度對比

方法時間複雜度備註
每次排序O(n² log n)原始碼做法,n≤5000 可能超時
最小堆O(n log n)推薦做法,每次取最小、插入均為 log n

注意事項

  • 輸入包含多組測試用例,以 n=0 結束
  • 數據範圍需用 long long 防止溢出
  • 若僅有一個數,無需合併,代價為 0
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved