平衡堆+貪心 hdu1588 合併果子
阿新 • • 發佈:2019-02-14
題意:貪心任意石子合併
思路:平衡堆的模板和程式碼測試
#include<map> #include<set> #include<cmath> #include<ctime> #include<stack> #include<queue> #include<cstdio> #include<cctype> #include<string> #include<vector> #include<cstring> #include<iostream> #include<algorithm> #include<functional> #define fuck(x) cout<<"["<<x<<"]" #define FIN freopen("input.txt","r",stdin) #define FOUT freopen("output.txt","w+",stdout) using namespace std; typedef long long LL; typedef pair<int, int>PII; const int MX = 1e3 + 5; int rear; LL S[MX << 2]; void push(LL x) { int now = ++rear, pre = now >> 1; S[now] = x; while(pre && S[pre] > S[now]) { swap(S[now], S[pre]); now = pre, pre = now >> 1; } } void pop() { S[1] = S[rear--]; int now = 1; while((now << 1) <= rear) { int lt = now << 1, rt = now << 1 | 1; if(rt <= rear) { if(S[lt] >= S[now] && S[rt] >= S[now]) break; if(S[now] >= S[lt] && S[rt] >= S[lt]) swap(S[now], S[lt]), now = lt; else swap(S[now], S[rt]), now = rt; } else { if(S[lt] > S[now]) break; swap(S[now], S[lt]), now = lt; } } } int main() { int T, n; //FIN; scanf("%d", &T); while(T--) { rear = 0; scanf("%d", &n); for(int i = 1; i <= n; i++) { int t; scanf("%d", &t); push(t); } LL ans = 0, sum; for(int i = 1; i <= n - 1; i++) { sum = S[1]; pop(); sum += S[1]; pop(); ans += sum; push(sum); } printf("%lld\n", ans); } return 0; }