假设当前置顶了条信息,学生对信息的期望贡献如下:
如果没被置顶,那么贡献为0
如果被置顶了,那么选出条信息包含的概率为,选出条信息包含的概率为
明显的,如果确定了,那么每条信息的期望都能确定,取出期望前大的信息,就是置顶了条信息时能得到的最大期望。
考虑,如果都小于或等于,那么当增大时,分子不变,那么置顶了条信息时能得到的最大期望减小。
所以最多自需要枚举,然后取期望之和最大的那个答案。
code
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=2e5+7,mod=1e9+7;
struct app{
int x,y;
bool operator<(const app& a)const{
return x>a.x;
}
}a[maxn];
int m[maxn],k[maxn];
signed main() {
cin.sync_with_stdio(false), cin.tie(nullptr),cout.tie(nullptr);
int n;
cin>>n;
for(int i=1;i<=n;++i) {
cin>>m[i]>>k[i];
}
vector<int>ans;
double res=0.0;
for(int i=1;i<=20;++i) {
for(int j=1;j<=200000;++j) a[j]={0,j};
for(int j=1;j<=n;++j) {
if(k[j]>=i) a[m[j]].x+=i;
else a[m[j]].x+=k[j];
}
sort(a+1,a+200001);
double tmp=0.0;
vector<int>v;
for(int j=1;j<=i;++j) tmp+=a[j].x,v.emplace_back(a[j].y);
tmp/=i;
if(tmp>res) {
res=tmp;
ans=v;
}
}
cout<<ans.size()<<'\n';
for(auto i:ans) cout<<i<<' ';
return 0;
}