版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_37632935/article/details/84262392
题意:给你n个题目,每个题目的a[i]代表他所属的类别,举办若干场比赛,要求每一场比赛的题目数量是上一场题目数量的2倍,第一天的题目数量没有限制。求最大化的题目数量和。
思路:刚开始想二分一下最后一天的题目,然后判断一下,发现n的范围2e5,a[i]最大1e9,2e5*32可以直接暴力。我们假设当前最后一天的题目为p,那么我们一直除以2,判断他最多能举办几天然后累加一下题目即可,注意只有第一天的题目数量可以为奇数。
#include <bits/stdc++.h>
using namespace std;
map<int,int> m;
int a[200005];
int main()
{
int n;cin>>n;
for(int i=0;i<n;i++)
{
int x;cin>>x;
m[x]++;
}
for(map<int,int>::iterator it=m.begin();it!=m.end();it++) a[it->second]++;
int ans=0;
for(int i=n;i>=0;i--) a[i]+=a[i+1];
for(int i=1;i<=n;i++)
{
int sum=i;int num=1;
int p=i;
if(!a[i]) continue;
while(p%2==0)
{
p=p/2;num++;
if(a[p]<num) break;
sum+=p;
}
ans=max(ans,sum);
}
cout<<ans<<endl;
return 0;
}