[USACO22DEC] Cow College B 题解

洛谷 P8897

AcWing 4821

题目描述

\(n\)头奶牛,每头奶牛愿意交的最大学费为\(c_i\),问如何设置学费,可以使赚到的钱最多。

\(1\le n\le 10^5,1\le c_i \le 10^6\)

做法分析

首先看数据范围,猜下正解时间复杂度可能是\(O(n \log n)\)

对于任意学费\(tmp\),设愿意交的学费大于该费用的奶牛为\(num\)个,则现在的收益为\(tmp * num\)

显然我们将费用设为大于\(tmp\)的最小的一个\(c_x\),获得的总收益显然比现在更优,因为可交费的奶牛不变,但是交的费用\(c_x > tmp\)变大了。

因此我们就可以枚举每个\(c_i\)作为\(tmp\),那现在只需求出大于等于\(c_i\)的个数就行了。

可以从大到小排序,然后枚举每个\(c_i\),那大于等于\(c_i\)的个数就是现在的下标\(i\),也就是求最大的\(c_i * i\)

注意开long long

还有一个要注意的点是,当有多个解时,要输出学费最小的解。

排序\(O(n \log n)\),遍历\(O(n)\)

代码

#include<bits/stdc++.h>

#define ll long long
#define MAXn 100010

using namespace std;

int n;
ll a[MAXn], ans = 0, num;

inline bool com(ll a, ll b)
{
    return a > b;
}

int main()
{
    scanf("%d", &n);
    for(int i = 1; i <= n; i++)
        scanf("%lld", &a[i]);
        
    sort(a + 1, a + n + 1, com);
    
    for(int i = 1; i <= n; i++)
    {
        ll tmp = a[i] * i;
        if(tmp >= ans)//注意这里是大于等于
        {
            ans = tmp;
            num = a[i];
        }
        
    }
    
    printf("%lld %lld", ans, num);
    
    return 0;
}
posted @ 2023-01-01 15:06  six_one  阅读(86)  评论(0编辑  收藏  举报