Codeforces Round #521 (Div. 3) E - Thematic Contests (二分 + STL)

题目链接:http://codeforces.com/contest/1077/problem/E

题意:首先给你一个长度为n的序列,表示一共有n个问题。其中某些问题属于同一种话题。现在要让你举办一天接一天的比赛,每天比赛要选择这些话题中的选择一个话题来进行解决问题。每天的比赛有如下要求:

第一 :当天话题对应的问题的个数应该是前天的两倍。如:前一天我们讨论的是话题3,问题个数为2的话,当天我们就得选择一个问题个数为4的话题。

第二:我们要求总共解决问题的个数最大。而不是举办比赛的次数最大。

第三:第一天我们可以选择任意数量的问题。

题解:我们可以知道第一天的选择问题的个数,直接导致了后面选择话题。我们可以暴力枚举第一天选择了几个问题。然后只需要从按照问题数量从小到大的排好序的话题中依次挑选合适的即可。

我们用二分的方法来判断当天需要问题个数的位置。

所以解决问题过程如下:

第一:对话题按照问题数量排序。

第二:枚举第一天选择了多少问题

第三:计算第一天问题选择的个数 i 能总共选出多少问题。

第四:求最大值。

注意:

第一:这个不能用桶排序的方法记录每个话题的数量。因为话题的大小为1e9。所以我们用map来存。然后再把结果放回数组中。

第二:当我们选择问题的数量大于2e5时,可以直接跳出选择话题的过程。

代码如下:

#include<bits/stdc++.h>
using namespace std;

const int maxn = 2e5 + 10;
struct node{
	int key;
	int val;
	bool operator < (const node &a) const{
		return val > a.val;
	}
};
map<int,int> mp;
priority_queue<node> q;
int num[maxn];
int cnt ;

int slove(int x){
	int count = x;
	int flag = 1;
	int pos = 0;
	int sum = 0;
	while(flag){
		int s = lower_bound(num+pos,num+cnt,count) - num;
		if(s < cnt){
			pos = s + 1;
			sum += count;
			count <<= 1;
		}
		else flag = 0;
		if(count > maxn) flag = 0;
	}
	return sum ;
	
}
int main(){
	int n;
	scanf("%d",&n);
	for(int i = 0 ; i < n ; i ++){
		int tmp;
		scanf("%d",&tmp);
		mp[tmp] ++;
	}
	map<int,int>::iterator it;
	for(it = mp.begin() ; it != mp.end() ; it ++){
		node now;
		now.key = it->first;
		now.val = it->second;
		q.push(now);
		//cout <<it->first << " " << it->second << endl;
	}
	cnt = 0;
	while(!q.empty()){
		node now  = q.top();
		num[cnt ++] = now.val;
		q.pop();
	}
	int ans = -1;
	for(int i = 0 ; i < maxn ; i ++){
	//	cout << ans << endl;
		ans = max(ans,slove(i));
	}
	cout << ans << endl;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值