ABC57 Maximum Average Sets(组合数学)

文章讨论了一个关于找出使平均值最大的子集的问题,其中涉及到了组合数学中的杨辉三角计算组合数,以及对数组排序和查找最小值的算法。代码使用C++实现,通过预处理组合数并分析子集中最小值的数量来确定最大平均值和可能的方案数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Maximum Average Sets

根据题意可知,当取a个的时候平均值是最大的,因为如果再取,一定是比取的第a个小或者等于第a个,所以平均值并不会增加,这样就得到了第一个答案,其次是有多少种方案,因为n<=50,所以可以用杨辉三角预处理求组合数,因为选取的a个数中能改变的只能是其中最小的数,不难证任意改变不是最小的数的话,平均值一定会变,所以考虑最小的数有多少个和选取的a个数中有多少个最小值,如果a中最小值的个数小于最小值一共的数量,说明a中不止存在最小值,还存在更大的数,此时并不能选取更多一直到b个数,所以只能在C[n,m]中选择,如果a中全是最小值,说明如果再往里加入最小值一直到b个数的话平均值不会改变,但方案数是会改变的,此时就需要累加C[n,a]+C[n,a+1]...有多少个就加到多少

AC代码:

#include <bits/stdc++.h>
using namespace std;
using LL = long long;
int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    vector<vector<LL>> c(65, vector<LL> (65));
    for (int i = 0; i < 55; i++){
        for (int j = 0; j <= i; j++){
            if (!j) c[i][j] = 1;
            else c[i][j] = (c[i - 1][j] + c[i - 1][j - 1]);
        }
    }
    int n, a, b;
    cin >> n >> a >> b;
    vector<LL> v(n);
    double ave = 0.0, ans = 0.0;
    map<LL, LL> mp;
    for (int i = 0; i < n; i++) {
        cin >> v[i];
        mp[v[i]]++;
    }
    sort(v.begin(), v.end());
    vector<LL> z;
    int len = 0;
    for (int i = n - 1; i > n - 1 - a; i--) {
        z.push_back(v[i]);
        ave += v[i];
    }
    ans = ave / a;
    int cnt = 0;
    LL minn = *min_element(z.begin(), z.end());
    for (int i = 0; i < a; i++) {
        if (minn == z[i]) {
            cnt++;
        }
    }
    cout << fixed << setprecision(10) << ans << '\n';
    LL q = 0;
    if(cnt < a) {
        q = c[mp[minn]][cnt];
    } else {
        for(int i = a; i <= b && mp[minn] >= i; i++) {
            q += c[mp[minn]][i];
        }
    }
    cout << q << '\n';;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值