题目链接:https://codeforces.com/contest/1612/problem/E
分析
可以枚举取
t
t
t个位置。
根据每个位置
k
k
k值的和降序排序,注意每个
k
k
k最大为
t
t
t,因为
k
k
k最大只有
20
20
20,所以最多设置前
20
20
20个位置。
把
20
20
20种情况都跑一遍算一遍期望取最大就是答案。
具体看代码
代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
#define fi first
#define se second
#define lson (k << 1)
#define rson (k << 1 | 1)
const ll LINF = 1e18;
const int INF = 1e9 + 7;
const int N = 2e5 + 10;
const int M = 1e6 + 10;
const ll P = 998244353;
const double eps = 1e-7;
int n, cnt;
int sum[N], sumk[N];
pii c[N];
vector<int> a, b[N];
bool cmp(int x, int y){if(sumk[x] == sumk[y]) return sum[x] > sum[y];return sumk[x] > sumk[y];}
int main()
{
scanf("%d",&n);
for(int i=1,p,k;i<=n;i++)
{
scanf("%d%d",&p,&k);
if(!sum[p]) a.push_back(p), cnt++;
sum[p]++;
sumk[p] += k;
b[p].push_back(k);
c[i].first = p;
c[i].second = k;
}
double mx = 0;
int ans = 0;
for(int t=1;t<=min(20, cnt);t++)
{
for(int i=0;i<a.size();i++) sumk[a[i]] = 0;
for(int i=1;i<=n;i++) sumk[c[i].first] += min(c[i].second, t);
sort(a.begin(), a.end(), cmp);
double ex = 0;
for(int j=0,p;j<t;j++)
{
p = a[j];
if(sum[p] == 0) break;
for(int x=0;x<b[p].size();x++)
ex += min(1.0, 1.0 * b[p][x] / t);
}
if(ex > mx) mx = ex, ans = t;
}
printf("%d\n",ans);
for(int i=0;i<ans;i++) printf("%d ",a[i]);
return 0;
}