C/C++教程

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 << ' ';
}
这篇关于cf1612 E. Messages的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!