@[a13901280570](/user/1070752) 本题不能使用简单的排序,因为要保证全局最优,就必须合并一次排一次序,到时这样时间就会超标,所以我们使用 stl 里面的优先队列。
**思路如下:** 首先把所有果子堆数塞进优先队列,然后循环,每次取出最少的两堆,合并在一起,并把合并的代价加入结果,再把两个果子合并后的堆数塞进优先队列,重复以上操作直到只剩一堆果子。
因为优先队列自带单调性,所以不需要排序,懂?
by Y_QWQ_Y @ 2024-01-19 23:33:51
@[Y_QWQ_Y](/user/677091) 您所说的优先队列是栈或者堆吗?我刚接触编程,还没有系统学习到队列的相关知识,有关栈和堆的简单题都还不会,这个题是不是没法完成了。
如果要考虑全局最优,是不是就不能用常规意义上的贪心算法,只考虑眼前最优了?
我还没有学算法,是自己在一些网站看的有关贪心这部分的内容,理解比较浅,感谢您的解答
by a13901280570 @ 2024-01-19 23:53:48
> 您所说的优先队列是栈或者堆吗?
堆。
> 如果要考虑全局最优,是不是就不能用常规意义上的贪心算法,只考虑眼前最优了?
是这样的。
by whhsteven @ 2024-01-20 01:03:15
AC
```c
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e4+3;
int n,k,a[maxn];
int main(){
scanf("%d",&n);
for (int i=1;i<=n;i++) scanf("%d",&a[i]);
sort(a+1,a+n+1); reverse(a+1,a+n+1);
int ans=0;
while (n>1){
ans+=a[n-1]+a[n];
a[n-1]=a[n-1]+a[n]; n--;
int p=n;
while (p>1&&a[p]>a[p-1]) swap(a[p],a[p-1]),p--;
}
printf("%d\n",ans);
return 0;
}
```
by timmyliao @ 2024-01-20 07:20:48