2004

合併果子

題目鏈接:題目

思路:首先看到這題就開始的想法是每次進行一次排序,拿出兩個最小的,合併後再丟進去。然後重複操作…..但是這樣寫每次都要sort一次,數據一大不免會超時。所以就優先隊列寫是正解,當然針對於這一題還可以set庫中的multiset來寫

代碼:

//優先隊列寫法!!!!!!!!!!!!!!!!!!!
#include <iostream>
#include <queue>
using namespace std;

//Statement_common
int n,ans;
int a[10001];
priority_queue<int> zhou;

int main()
{
    cin>>n;
    for(int i=1;i<=n;i++) cin>>a[i],zhou.push(-a[i]);

    for(int i=1;i<=n-1;i++)
    {
        int c=0,cc=0,ccc=0;

        //大小根堆的轉換
        c=-zhou.top(),zhou.pop();
        cc=-zhou.top(),zhou.pop();
        ccc=c+cc;

        ans+=ccc,zhou.push(-ccc);
    }

    cout<<ans;
    return 0;
}
//注意,優先隊列默認初始化爲大根堆,即從大到小,所以乘1個-1轉換成小根堆
//set庫multiset寫法!!!!!!!!!!!!!!!!
#include <iostream>
#include <set>
using namespace std;

//Statement_common
int n,ans;
int a[10001];
multiset<int> zhou;

int main()
{
    freopen("fruit.in","r",stdin);
    freopen("fruit.out","w",stdout);

    cin>>n;
    for(int i=1;i<=n;i++) cin>>a[i],zhou.insert(a[i]);

    for(int i=1;i<=n-1;i++)
    {
        int c=0,cc=0,ccc=0;
        c=*zhou.begin();
        zhou.erase(zhou.begin());

        cc=*zhou.begin();
        zhou.erase(zhou.begin());

        ccc=c+cc,ans+=ccc;
        zhou.insert(ccc);
    }

    cout<<ans;
    return 0;
    /*
    這題之所以用set庫是利用了set中multiset多重集合的重複性,即可以存在有
    重複的元素。而且,set和multiset可以自動排序(從小到大),這一點很重要,
    這一題正是利用了這點。並且效率並超越sort,所以不會TLE。
    至於爲什麼效率快,查了一下資料,如下解釋:

        set的含義是集合,它是一個有序的容器,裏面的元素都是排序好的。
        支持插入,刪除,查找等操作,就像一個集合一樣。所有的操作的都是
        嚴格在logn時間之內完成,效率非常高。

        爲什麼是logn呢?
        因爲set和multiset都是基於紅黑樹實現的。

    好吧現在紅黑樹好像是什麼平衡二叉樹什麼東西的,沒有深究....(先用着先)
    總之來說掌握STL中的set庫也是蠻好的一件事
    */
}

補充:優先隊列(queue)和multiset(set)相關知識可以轉到我的STL總結去學習


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