P1090 [NOIP2004 提高组] 合并果子
https://www.luogu.com.cn/problem/P1090
贪心,二叉堆,优先队列
黄色题
贪心,二叉堆,优先队列
黄色题
思路:
大致思路也就是,先找到两个最小的,取出来,相加再放进去,但如果每次取之前都进行一次排序的话就会超时,所以不排序直接找到最小的和次小的。
大致思路也就是,先找到两个最小的,取出来,相加再放进去,但如果每次取之前都进行一次排序的话就会超时,所以不排序直接找到最小的和次小的。
#include<bits/stdc++.h> using namespace std; int n,a[10005],sum; void pd(int x) { int p=x; for(int i=p+1; i<=n; i++) { if(a[p]>a[i]) { p=i; } } swap(a[x],a[p]); } int main() { cin>>n; for(int i=1; i<=n; i++) { cin>>a[i]; } pd(1); pd(2); for(int i=2; i<=n; i++) { a[i]+=a[i-1]; sum+=a[i]; pd(i); pd(i+1); } cout<<sum; return 0; }
写法二:优先队列
#include<stdio.h> #include<queue> #include<string.h> #include<algorithm> using namespace std; struct node { int m; bool operator<(const node &a) const//优先队列,重量小的在前 { return a.m<m; } }; int main() { int i,j,n,sum; priority_queue<node>Q; node p,q; while(~scanf("%d",&n)) { for(i=0; i<n; i++) { scanf("%d",&p.m); Q.push(p); } sum=0; for(i=0;i<n-1;i++)//n个果子只需要n-1次合并 { p=Q.top(),Q.pop(); q=Q.top(),Q.pop(); sum+=p.m+q.m; p.m=p.m+q.m; Q.push(p); } while(!Q.empty()) Q.pop(); printf("%d\n",sum); } return 0; }