【洛谷】P1090 合并果子
这道题很经典 。 考点:二叉堆,贪心
我写了两个版本。顺便复习一下手工堆。
系统堆版:
#include<bits/stdc++.h> using namespace std; priority_queue <int> q; int main() { int n; long long ans = 0; scanf("%d",&n); for (int i = 1 , x ; i <= n ; i ++) { scanf("%d",&x); q.push(-x); } for (int i = 1 , tmp ; i < n ; i ++) { tmp = q.top(); ans -= q.top(); q.pop(); tmp += q.top(); ans -= q.top(); q.pop(); q.push(tmp); } cout<<ans<<endl; return 0; }
手工堆版:
#include<bits/stdc++.h> using namespace std; int n,a[10005]; long long ans; void insert(int x) { int father = x / 2; if (father == 0) return; if (a[father] > a[x]) { swap(a[father],a[x]); insert(father); } } void change(int x,int maxn) { int child = x*2; if (child > maxn) return; if (child + 1 <= maxn && a[child]>a[child+1]) child ++; if (a[x]>a[child]) { swap(a[x],a[child]); change(child,maxn); } } int main() { scanf("%d",&n); for (int i = 1 ; i <= n ; i ++) { scanf("%d",&a[i]); insert(i); } while (n>1) { int x = a[1]; a[1] = a[n]; change(1,--n); a[1] += x; ans += a[1]; change(1,n); } cout<<ans<<endl; return 0; }