2020 算法上机赛 C2 - B 减半
题面
Kazamori 有 \(n\) 个正整数。每次操作可以使一个数的值变为原来的一半(除以 2 向下舍入)。现在 Kazamori 想知道,进行 \(k\) 次操作后,这些数的和的最小值是多少。
输入
多组输入数据
每组数据第一行两个正整数 \(n,k\) , 接下来一行用空格隔开的 \(n\) 个正整数 \(a_i\)。
输出
每组数据输出一行,一个整数,表示和的最小值。
输入样例
1 1
3
输出样例
1
数据范围
\(1≤n≤10^5,1≤k≤10^5\)
\(1≤ai≤10^9\)
做法
贪心,每次选出最大的数字进行操作
找最大值的过程用一个堆维护,复杂度 \(O(n\log n)\)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
inline ll read() {
ll q=0,w=1;char c=getchar();
while(!isdigit(c)){if(c=='-')w=-1;c=getchar();}
while(isdigit(c))q=q*10+c-'0',c=getchar();
return w*q;
}
ll n, k; long long ans;
void work() {
priority_queue<ll> Q;
for(int i = 1;i <= n; ++i) {
ll x = read(); ans += x;
Q.push(x);
}
while(k--) {
ll x = Q.top(); Q.pop(); ans -= x;
x = x / 2; Q.push(x); ans += x;
}
cout << ans << endl;
}
int main() {
while(scanf("%lld%lld", &n, &k) != EOF) {
ans = 0;
work();
}
return 0;
}

浙公网安备 33010602011771号