链接:https://ac.nowcoder.com/acm/contest/8563/A
来源:牛客网
题目描述
给一个数组,一共有 n个数。
你能进行最多 k次操作。每次操作可以进行以下步骤:
选择数组中的一个偶数 a i a_i ai,将其变成 a i / 2 a_i/2 ai/2 。
现在你进行不超过 次操作后,让数组中所有数之和尽可能小。请输出这个最小的和。
输入描述:
第一行输入两个正整数 和 ,用空格隔开
第二行输入个正整数 aia_iai
数据范围:
1 ≤ n ≤ 100000 , 1 ≤ k ≤ 1 0 9 1≤n≤100000,1≤k≤10^9 1≤n≤100000,1≤k≤109
1 ≤ n ≤ 100000 , 1 ≤ k ≤ 1 0 9 1 ≤ n≤100000,1≤k≤10^9 1≤n≤100000,1≤k≤109
1 ≤ n ≤ 100000 , 1 ≤ k ≤ 1 0 9 1≤n≤100000,1≤k≤10^9 1≤n≤100000,1≤k≤109
1 ≤ a i ≤ 1 0 9 , 1 ≤ a i ≤ 1 0 9 1 ≤ a i ≤ 1 0 9 1≤ai≤10^9,1≤a_i≤10^91≤ai≤10^9 1≤ai≤109,1≤ai≤1091≤ai≤109
输出描述:
一个正整数,代表和的最小值。
示例1
输入
5 3
2 4 8 10 11
输出
24
说明
对8操作2次,对10操作1次,最后的数组是2 4 2 5 11。可以证明这样的操作是最优的。
题解
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+7;
priority_queue<int>f; long long ans=0;
int main(){
int n,k; cin>>n>>k;
for(int i=1;i<=n;i++){
int c; scanf("%d",&c);
if(c%2==0) f.push(c); else ans+=c;
}
while(k>0&&f.size()){
int x=f.top(); f.pop();
x/=2,k--; if(x%2==0) f.push(x); else ans+=x;
}
while(f.size()) ans+=f.top(),f.pop(); cout<<ans<<endl;
return 0;
}