信息学奥赛一本通 贪心算法
【题目描述】
在黑板上写了N个正整数作成的一个数列,进行如下操作:每一次擦去其中的两个数a和b,然后在数列中加入一个数a×b+1,如此下去直至黑板上剩下一个数,在所有按这种操作方式最后得到的数中,最大的max,最小的为min,则该数列的极差定义为M=max−min。
【输入】
第一行,一个数为N;
第二行,N个数。
【输出】
输出极差。
【输入样例】
3
1 2 3
【输出样例】
2
【分析】
尝试用样例数据进行计算,发现升序结果大,降序结果小。可采用贪心的算法,每次取队列前两个进行计算,将计算结果再插入到队列中去,直到队列中只剩下一个数据。每插入一个数据,都要重新排序,所以用优先队列比较合适。
priority_queue<int,vector<int>,less<int>> a; //大顶堆 ,降序
priority_queue<int,vector<int>,greater<int>> b; //小顶堆 ,升序
【完整代码】
#include <bits/stdc++.h>
using namespace std;
int main(int argc, char *argv[]) {
priority_queue<int,vector<int>,less<int>> a; //大顶堆 ,降序
priority_queue<int,vector<int>,greater<int>> b; //小顶堆 ,升序
int n;
cin >> n;
for(int i = 0; i < n; i++){
int t;
cin >> t;
a.push(t);
b.push(t);
}
//取二,添加一
while(a.size()>1){
int t1,t2;
t1 = a.top();
a.pop();
t2 = a.top();
a.pop();
a.push(t1 * t2 + 1);
t1 = b.top();
b.pop();
t2 = b.top();
b.pop();
b.push(t1 * t2 + 1);
}
//小顶堆 - 大顶堆
int result = b.top() - a.top();
cout << result;
return 0;
}