![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
//思路:这题思路似乎很简单,每次取出最小的两个堆合并, //但是由于数据太大,不能采取每次进行排序的方式,所以 //想到用优先队列,以数据小的优先级更高为标准,但是 //优先队列中的数据默认情况下是由大到小弹出的,所以多一步 //操作,具体如下: #include<cstdio> #include<queue> using namespace std; #define LL long long struct node{ long long x; friend bool operator < (node a, node b){ return a.x < b.x; //默认情况下从大到下弹出。 } }; priority_queue<LL,vector<LL>,greater<LL> > q; //从小到大弹出。 //你现在觉得太复杂的话,记住就行了。有兴趣自己查资料。对了, //注意最后两个>之间是有个空格的,不然会编译错误。 int main() { int n; long long x, sum, tmp; while(~scanf("%d", &n)) { while(!q.empty()) q.pop(); //一般加上这步比较保险,虽然这题不加也是对的。 while(n--) { scanf("%I64d", &x); q.push(x); } if(n == 1) { printf("%I64d", q.top()); //如果只有一个数,直接弹出,输出即可。 continue; } sum = 0; while(1) { tmp = 0; tmp += q.top(), q.pop(); //弹出最小的两个。 tmp += q.top(), q.pop(); sum += tmp; if(q.empty()) break; //如果是空队列,则跳出。 q.push(tmp); //将相加之后的结果压入队列中。 } printf("%I64d ", sum); } return 0; }