其他分享
首页 > 其他分享> > cf1612 E. Messages

cf1612 E. Messages

作者:互联网

题意:

导师有 \(n\) 个学生和多条消息,现可以置顶若干条消息,每个学生只会看被置顶的消息中的随机的 \(k_i\) 条。导师希望第 \(i\) 个学生看到编号为 \(m_i\) 的消息,问置顶哪些消息可以最大化看到该看的消息的学生的数量的期望

\(1\le n,m_i\le 2e5,1\le k_i\le 20\)

思路:

假设置顶 \(t\) 条消息。对每条消息 \(m'\),如果选它的话,贡献就是 \(\frac {\min\{t,k_i\}}{t}[m_i=m']\)。置顶贡献前 \(t\) 大的消息即可。

只需枚举 \(t\le 20\),因为 \(t>20\) 时分子一定是 \(k_i\),增大分母只会使答案变小

const signed N = 3 + 2e5;
int n, m[N], k[N];
db ans[21]; vector<int> choose[21];
void sol() {
    cin >> n;
    for(int i = 1; i <= n; i++) cin >> m[i] >> k[i];

    for(int t = 1; t <= min(n,20); t++) {
        vector<PII> f(N, {0,0}); //贡献,消息id
        for(int i = 1; i < N; i++) f[i].se = i;
        for(int i = 1; i <= n; i++) f[m[i]].fi += min(t, k[i]);

        sort(all(f), greater<PII>());
        for(int i = 0; i < t; i++)
            ans[t] += (db)f[i].fi / t, choose[t].pb(f[i].se);
    }

    int t = max_element(ans + 1, ans + 1 + 20) - ans;
    cout << t << endl;
    for(int i : choose[t]) cout << i << ' ';
}

标签:le,20,int,Messages,cf1612,消息,ans,置顶
来源: https://www.cnblogs.com/wushansinger/p/16448876.html