题目的解法属于贪心,因为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