题解
题目大意 每天完成若干个相同的任务 第二天完成的数量要求是前一天的两倍 不同天不能完成相同的任务 问最大任务完成数量
统计相同编号的数量 向前做前缀和 暴力枚举最后一次的完成数量 每次除以二检测当前数量-天数(减去向前前缀和的贡献)是否大于0 大于则满足 每次结束检测是否为奇数 乘二不可能为奇数所以跳出
AC代码
#include <stdio.h>
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const int MAXN = 2e5 + 10;
int a[MAXN];
int main()
{
#ifdef LOCAL
freopen("C:/input.txt", "r", stdin);
#endif
map<int, int> mp;
int N;
cin >> N;
for (int i = 0; i < N; i++)
{
int x;
scanf("%d", &x);
mp[x]++;
}
for (auto it = mp.begin(); it != mp.end(); it++) //统计数字出现次数
a[it->second]++;
for (int i = N; i >= 1; i--) //次数做前缀和 出现多的可以当做少的用
a[i] += a[i + 1];
int ans = 0;
for (int i = 1; i <= N; i++) //暴力枚举最后一天的数量
{
int s = 0, cnt = 0; //求和 天数
for (int j = i; j >= 1; j >>= 1)
{
if (a[j] - cnt <= 0) //减去天数为当前次数的数量
break;
s += j;
cnt++;
if (j & 1) //2的倍数不可能为奇数
break;
}
ans = max(ans, s);
}
cout << ans << endl;
return 0;
}