Add All -uva优先队列的应用

题目的解法属于贪心,因为cost=a1+a2,所以要保证每次的cost最小,所以说,每次将队列中最小的两个相加,得出来的数放入队列中,再取2个最小的相加,直到全部加完,所以这就涉及了一个取2个最小数的问题,我说一下我一开始的做法
#include<stdio.h>
#include<iostream>
#include<stdlib.h>
using namespace std;
#define MAX_SIZE 10000 + 10
int cmp(const void *a,const void *b)
{
    return *(int*)a-*(int*)b;
}
int main()
{
    int i,n;
    for(;scanf("%d",&n);)
    {
        int num[MAX_SIZE]={0};
        int temp=0,sum=0;
        int front=0,back=n-1;
        if(!n) break;
        for(i=0;i<n;i++)
        scanf("%d",&num[i]);
        while(front<back) /*只有一个数的时候程序结束*/
        {
            qsort(num+front,back-front+1,sizeof(num[0]),cmp);
            /*每次都要排序*/
            temp=num[front]+num[front+1];
            /*printf("%d\n",front);
            printf("%d + %d = %d\n",num[front],num[front+1],temp);*/
            sum+=temp;
            front+=2;
            back++;
            num[back]=temp;
        }
        printf("%d\n",sum);
    }
    return 0;
}

这种算法是超时的,因为我每次都对队列进行了一次排序

下面是使用优先队列的算法

#include<stdio.h>
#include<iostream>
#include<stdlib.h>
#include<queue>
#include<algorithm>
#include<vector>
using namespace std;
int main()
{
    int i,n;
    priority_queue < int,vector<int>,greater<int> >q;
    /*优先队列*/
    while(scanf("%d",&n)&&n)
    {
        int temp,sum=0;
        /*printf("%d\n",n);*/
        for(i=0;i<n;i++)
        {
            scanf("%d",&temp);
            q.push(temp);
        }
        while(!q.empty())
        {
            /*printf("%d\n",sum);*/
            int n1,n2,n3;
            n1=q.top();
            q.pop();
            if(q.empty())
            break;
            n2=q.top();
            q.pop();
            n3=n1+n2;
            sum+=n3;
            q.push(n3);
            /*printf("%d\n",sum);*/
        }
        printf("%d\n",sum);
    }
    return 0;
}

优先队列一开始我也不会,之后上网查了一下别人的资料,自己写出来了

参考资料:http://blog.csdn.net/shuangde800/article/details/7327759

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值