【vijos】【优先队列】合并果子

贪心每次选最小的两堆合并即可。
注意STL自带的优先队列是大根堆,排序是降序排列,升序需要把缺省的比较函数换成greater(也是STL自带)

#include <cstdio>
#include <queue>
using namespace std;

int n,a[10010],ans=0;
priority_queue<int, vector<int>, greater<int> > q;

int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++) {
        scanf("%d",&a[i]);
        q.push(a[i]);
    }
    for(int i=1;i<=n-1;i++){
        int temp=q.top();
        q.pop();
        temp+=q.top();
        q.pop();
        q.push(temp);
        ans+=temp;
    }
    printf("%d",ans);
    return 0;
}

顺便学习一下优先队列的基本方法

#include<queue>
using namespace std;
//优先队列的声明
priority_queue<int> q1;
//从小到大排序的优先队列
priority_queue<int, vector<int>, greater<int> > q2;
//自定义结构体的优先队列
priority_queue<node> q3;
bool operator < (node a1, node a2){
    return a1.x<a2.x ? true : false;
{
//或者把operator定义在结构体内部
struct Node{
    int x, y;
    Node(int a=0, int b=0):
        x(a), y(b) {}
    friend operator <(Node a,Node b){
    if(a.x==b.x) return a.y>b.y;
    return a.x>b.x;
    }
};

剩下的把queue里面的front()换成top()就好啦

顺便贴一道母题《均分纸牌》的代码(超简单)

#include <cstdio>
using namespace std;

int n,a[200];

int main(){
    int ans=0,sum=0;
    scanf("%d",&n);
    for(int i=1;i<=n;i++) {
        scanf("%d",&a[i]);
        sum+=a[i];
    }
    int avg=sum/n;
    for(int i=1;i<=n;i++) {
        if(a[i]!=avg){
            ans++;
            a[i+1]-=(avg-a[i]);
        }
    }
    printf("%d
",ans);
    return 0;
} 
原文地址:https://www.cnblogs.com/leotan0321/p/6081413.html