题意:
n个问题,每个问题有一个标记ai,ai相同的问题是一个组,每天有一个组出题,每个组最多可以出一次题,题目的数目不超过自己组的题目数,第一天出题的组可以出若干道题,以后每天的出题数是前一天出题数的2倍。没有时间限制,问最多能出多少道题。
1 <= n <= 2e5 , 1 <= ai <= 1e9。
题解:
1.先将ai序列按从小到大排序,然后统计每个ai的出现次数,存储在b数组中,b数组从小到大排序。共有cnt个组。
2.枚举1~b[cnt]作为最后一天的出题数,然后统计总题数,最后找到最大总题数。
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
#include<vector>
#include<stack>
#include<map>
#define N 200005
#define mod 1000000007
using namespace std ;
int main()
{
int i , j ;
int n , x ;
int cnt ;
int a[N] , b[N] ;
int ans = 0 , sum , temp ;
scanf("%d" , &n) ;
for(i = 1 ; i <= n ; i ++)
scanf("%d" , &a[i]) ;
sort(a + 1 , a + n + 1) ;
memset(b , 0 , sizeof(b)) ;
cnt = 1 ;
b[cnt] ++ ;
for(i = 2 ; i <= n ; i ++)
if(a[i] == a[i - 1])
b[cnt] ++ ;
else
b[++ cnt] ++ ;
sort(b + 1 , b + cnt + 1) ;
for(i = 1 ; i <= b[cnt] ; i ++)
{
j = cnt ;
sum = i ;
temp = i ;
while(temp % 2 == 0 && j - 1 >= 1 && b[j - 1] >= temp / 2)
{
j -- ;
temp /= 2 ;
sum += temp ;
}
ans = max(ans , sum) ;
}
printf("%d\n" , ans) ;
}