我的天啊,这三题code都一样
题目大意
给你一些数,每次可以选取两个相加成为一个,新数即为得分。所有数加成一个后,求最小得分。
分析
其实就是每次选两个最小的数相加再放回数列中。
如果用sort效率极低(每次都要sort,时间复杂度为O(n^2*logn))
那么,我们的队列出厂(当当当当)
Code
#include<iostream>
#include<cstdio>
#include<queue>
using namespace std;
long long int i,m,n,j,k;
priority_queue<long long int>a;
int main(){
cin>>n;
for(i=1;i<=n;i++){
scanf("%d",&k);
a.push(-k);
}
for(i=1;i<n;i++){
int x,y;
x=-a.top();
a.pop();
y=-a.top();
a.pop();
m+=x+y;
a.push(-x-y);
}
cout<<m;
return 0;
}
队列
其实上面的代码用到了优先队列
队列
先进先出(First In First Out,FIFO)表。STL中为queue。
queue可以在头部弹出、尾部压入。
queue<data>a | 定义一个data形的队列 |
queue<data>a(b) | 队列a为队列b的副本 |
a.push(x) | 在队列尾部压入x |
a.pop() | 弹出队列顶部的元素 |
a.top() | 访问队首元素 |
其他懒得写 | 这些就够了 |
优先队列
优先队列与队列的区别就是优先队列队首元素是最大的。
普通的优先队列为大根堆,若要转化成小根堆只需元素取相反数即可。
priority_queue<data>a | 定义一个data形的队列 |
priority_queue<data>a(b) | 队列a为队列b的副本 |
a.push(x) | 在队列尾部压入x |
a.pop() | 弹出队列顶部的元素 |
a.top() | 访问队首元素 |
其他也懒得写 | 这些也就够了 |