合併果子(佇列和優先佇列)
阿新 • • 發佈:2018-12-11
有兩種方法 一種是佇列 一種是優先佇列(priority_queue)
這兩種方法的區別是佇列定義時沒有自動排序 所以只能在輸入的時候按順序才能輸出正解(所以佇列的方法不被認為是正解) 下面是程式碼 比較簡便:
#include<bits/stdc++.h>
using namespace std;
queue<int>q;
int main() {
int n,x;
cin>>n;
for(int i=0;i<n;i++) {
cin>>x;
q.push(x);
}
int ans=0;
for (int i=1;i<n;i++) {
ans+=q.front();
q.pop();
ans+=q.front();
q.pop();
q.push(ans);
}
cout<<ans;
}
但是如果用了優先佇列的話,剛開始就給你的是一個大根堆(從大到小排序)如果想讓這個佇列等價於一個小根堆,就可以入隊的時候加一個負號,eg:(-1 -2 -9)這樣就會按照絕對值從小到大排列 於是計數的時候用ans減去q.top()就ok了 然後這時候需要一個tmp來記錄下來合併果子的和,然後將合併後的果子放到隊尾 程式碼實現:
#include <bits/stdc++.h>
using namespace std;
priority_queue<int>q;
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int n,x;
cin>>n;
for(int i=0;i<n;i++) {
cin>>x;
q.push(-x);
}
int ans=0,tmp;
while(q.size()>1) {
tmp=q.top();
ans-=q.top ();
q.pop();
tmp+=q.top();
ans-=q.top();
q.pop();
q.push(tmp);
}
cout<<ans;
}
前幾行是關閉同步,可以加速。 while的地方可以改寫成for迴圈的形式:
#include<bits/stdc++.h>
using namespace std;
priority_queue<int>q;
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int n,x;
cin>>n;
for(int i=0;i<n;i++) {
cin>>x;
q.push(-x);
}
int ans=0,tmp;
for(int i=1;i<n;i++){
tmp=q.top();
ans-=q.top();
q.pop();
tmp+=q.top();
ans-=q.top();
q.pop();
q.push(tmp);
}
cout<<ans;
}
就是這樣