A题:除2! (贪心算法)

链接: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 1n1000001k109
1 ≤ n ≤ 100000 , 1 ≤ k ≤ 1 0 9 1 ≤ n≤100000,1≤k≤10^9 1n1000001k109
1 ≤ n ≤ 100000 , 1 ≤ k ≤ 1 0 9 1≤n≤100000,1≤k≤10^9 1n1000001k109
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 1ai109,1ai1091ai109
输出描述:

一个正整数,代表和的最小值。

示例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;
}

猜你喜欢

转载自blog.csdn.net/weixin_46339668/article/details/109703244