这大概是BZOJ里除了A+B Problem最水的一道题了吧
题面:http://www.lydsy.com/JudgeOnline/problem.php?id=1724
这道题其实有一些思路还是可以借鉴的
首先是逆向思维:为了让计算次数最多的边必须是最小的边,因此最小的和倒数第二小的必然在二叉树的最低端
接下来是递归(递推)的思想,将二者合并后,此问题又变为和合并前完全相同的问题,递推解决即可
维护自然就用priority_queue
#include <bits/stdc++.h> using namespace std; typedef long long ll; int n; priority_queue<int,vector<int>,greater<int> > q; inline int read() { char ch; int num,f=0; while(!isdigit(ch=getchar())) f|=(num=='-'); num=ch-'0'; while(isdigit(ch=getchar())) num=num*10+ch-'0'; return f?-num:num; } int main() { n=read(); for(int i=1;i<=n;i++) { int x=read(); q.push(x); } if(n==1){cout << q.top();return 0;} ll res=0; while(q.size()>1) { int x=q.top();q.pop(); int y=q.top();q.pop(); res+=(x+y); q.push(x+y); } cout << res; return 0; }