题目链接:题目
大意:
给定一个数组,你每次能选择两个数 a , b a,b a,b,将它们删去,并将 ( a + b ) / 2 (a+b)/2 (a+b)/2向下取整加入数字末尾,最大化最后剩余的数字。
思路:
如果你把这个过程写成算式会发现,结果就是所有数字相加,只不过每个数字被除以2的次数不同,而且越在前面的数被除得越多,所以可以排序,从最小的开始操作。
我使用的是优先队列,因为我觉得每次要取最小值,然后又要插入,特别适合优先队列,但是后来发现不用,因为每次插入的那个数仍然是最小的。
代码:
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define MOD 1000000007
#define fi first
#define se second
#define pii pair<int,int>
#define vec vector
void solve(){
int n;
cin >> n;
vec<int> a(n);
for(int i = 0; i < n; i++){
cin >> a[i];
}
priority_queue<int, vec<int>, greater<int>> pq;
for(int num : a){
pq.push(num);
}
while(pq.size() > 1){
int x = pq.top();
pq.pop();
int y = pq.top();
pq.pop();
pq.push((x + y) / 2);
}
cout << pq.top() << '\n';
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t=1;
cin >> t;
while(t--){
solve();
}
return 0;
}