c++10分,新手看不懂题解,求指点

P1090 [NOIP2004 提高组] 合并果子 / [USACO06NOV] Fence Repair G

@[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


|