UVA 10954 - Add All

http://uva.onlinejudge.org/external/109/10954.html

題意:

輸入一串數據,拿出兩個相加,把和放回去,再拿出兩個相加,把和放回去……依次循環,最後找出最小的和。

思路:

使用優先隊列+貪心,隊列按從小到大排列,每次選出隊首最小的2個數據,計算之後把和再放回隊列。也就是哈夫曼編碼算法。

Using a Priority Queue, you can greedily take the two smallest numbers, add them and insert them back into the Priority Queue. 

#include <iostream>
#include <queue>
#include <cstdlib>
#include <cstdio>
#include <cstring>
using namespace std;
class T{
    public :
        int n;
};

bool operator < (const T &t1, const T &t2)
{
     return t1.n > t2.n;
}
class AddAll{
    private:
        priority_queue<T> pri_que;
        int sum;
    public:
        void init();
        void process();
//        void output();
};
void AddAll::init(){
    while(!pri_que.empty())pri_que.pop();
    sum = 0;
}
void AddAll::process(){
    int num;
    T temp;
    while(cin>>num){
        if (num == 0)break;
        init();
        while(num--){
            cin>>temp.n;
            pri_que.push(temp);
        }
        while(!pri_que.empty()){
            T top1 ,top2 ,sumTop;
            top1 = pri_que.top();
            pri_que.pop();
            if(!pri_que.empty()){
                top2 = pri_que.top();
                pri_que.pop();
            }
            else
                top2.n = 0;
            sumTop.n = top1.n + top2.n;
            sum = sumTop.n + sum;
            if(!pri_que.empty())
                pri_que.push(sumTop);
        }
        cout<<sum<<endl;
    }
}
int main()
{
//    #ifndef ONLINE_JUDGE
//        freopen("D:\\acm.txt","r",stdin);
//    #endif // ONLINE_JUDGE


    AddAll addall;

    addall.process();
    return 0;
}


注意:要重載'<',使優先隊列從小到大排列。

 

測試數據:

數據來源:http://www.algorithmist.com/index.php?title=UVa_10954

 

Input

3
1 2 3
4
1 2 3 4
10
100000 100000 100000 100000 100000 100000 100000 100000 100000 100000 
5
2 2 2 2 3
0

 

 

 

 

 

 

 

Output 

9
19
3400000
26
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章