cf 1077e 思维 + 枚举

题意:

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) ;		 
}

猜你喜欢

转载自blog.csdn.net/Irving0323/article/details/87539068