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;  
}

 

posted @ 2022-08-09 08:53  -イレイナ  阅读(34)  评论(0)    收藏  举报